博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 使用Javascript作为脚本计算器
阅读量:6226 次
发布时间:2019-06-21

本文共 9650 字,大约阅读时间需要 32 分钟。

hot3.png

原则上Java 本身不支持脚本计算,早期通过ScriptManager或者J2V8支持脚本计算,但在Android中阉割了此部分功能,因此,为了能进行脚本计算,我们需要特别封装

import android.content.Context;import android.database.DataSetObserver;import android.graphics.Bitmap;import android.os.Build;import android.os.Handler;import android.os.Message;import android.util.Log;import android.webkit.ConsoleMessage;import android.webkit.JsResult;import android.webkit.ValueCallback;import android.webkit.WebChromeClient;import android.webkit.WebResourceError;import android.webkit.WebResourceRequest;import android.webkit.WebResourceResponse;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;import org.json.JSONException;import org.json.JSONObject;/** * Created by Noah on 2016/1/23. */public  class JavaScriptManager implements Handler.Callback{    //计算引擎    private WebView jsEngine;    //计算结果回调    private Handler.Callback mCallback;    //判断页面是否加载完成    private boolean isLoadFinished;    //表示加载完成    public final static int STATE_FINISHED = 200;    //返回正确结果    public final static int STATE_RESULT_OK = 100;    //计算出错    public final static int STATE_RESULT_FAILED = -100;    //加载开始    public final static int STATE_STARTING = 300;    private JavaScriptManager(Context context,Handler.Callback callback) {        jsEngine = new WebView(context);        initJsEngine();        this.mCallback = callback;    }    public static JavaScriptManager newInstance(Context context,Handler.Callback callback)    {        return new JavaScriptManager(context,callback);    }    private void initJsEngine()    {        if(jsEngine!=null)        {            WebSettings settings = jsEngine.getSettings();            settings.setCacheMode(WebSettings.LOAD_NO_CACHE);            settings.setAppCacheEnabled(false);            settings.setJavaScriptCanOpenWindowsAutomatically(false);            settings.setSupportMultipleWindows(false);            settings.setSaveFormData(false);            settings.setGeolocationEnabled(false);            settings.setJavaScriptEnabled(true);            settings.setSupportZoom(false);            settings.setDefaultTextEncodingName("utf-8");            jsEngine.setWebChromeClient(new JsEngineChromeClient(this));            jsEngine.setWebViewClient(new JsEngineWebClient(this));        }    }    @Override    public boolean handleMessage(Message msg) {        if(msg!=null)        {            if(msg.what==STATE_RESULT_OK)            {                return mCallback.handleMessage(msg);            }            else if(msg.what==STATE_FINISHED)            {                isLoadFinished = true;            }else if(msg.what==STATE_STARTING){                isLoadFinished = false;            }else{                Log.e("JavaScriptManager","ErrorCode="+msg.what+"description="+(String)msg.obj);                //防止脚本出错之后影响程序运行,有必要重新刷新                if(msg.what==STATE_RESULT_FAILED)                {                    jsEngine.reload();                }                return mCallback.handleMessage(msg);            }        }        return false;    }    public void loadWebData(String html)    {        if(isLoadFinished && jsEngine!=null)        {            jsEngine.loadData(html,"text/html;charset=utf-8","utf-8");        }    }        private String stringByEvaluatingJavaScriptFromString(String script){    try    {        Field field_webviewcore = android.webkit.WebView.class.getDeclaredField("mWebViewCore");        field_webviewcore.setAccessible(true);        Object obj_webviewcore = field_webviewcore.get(jsEngine);        Field field_BrowserFrame = obj_webviewcore.getClass().getDeclaredField("mBrowserFrame");        field_BrowserFrame.setAccessible(true);        Object obj_frame = field_BrowserFrame.get(obj_webviewcore);        Method method_stringByEvaluatingJavaScriptFromString = obj_frame.getClass().getMethod("stringByEvaluatingJavaScriptFromString", new Class[] {                java.lang.String.class        });        Object obj_value = method_stringByEvaluatingJavaScriptFromString.invoke(obj_frame, new Object[] {                script        });        return String.valueOf(obj_value);    }    catch(Exception e)    {        e.printStackTrace();        jsEngine.loadUrl(script);    }    return null;}    public void executeScript(String script)    {        if(jsEngine!=null)        {            if(Build.VERSION.SDK_INT>=19)            {                jsEngine.evaluateJavascript(script, new ValueCallback
() {                    @Override                    public void onReceiveValue(String message) {                        Message msg = new Message();                        try {                            JSONObject json = new JSONObject(message);                            msg.what = json.optInt("code",STATE_RESULT_OK);                            msg.obj = json.optString("result","");                        } catch (JSONException e) {                            e.printStackTrace();                            msg.what = -STATE_RESULT_FAILED;                        }                        JavaScriptManager.this.handleMessage(msg);                    }                });            }else{                stringByEvaluatingJavaScriptFromString("javascript:"+script);            }        }    }    private static class JsEngineWebClient extends WebViewClient{        public Handler.Callback callback;        public JsEngineWebClient(Handler.Callback callback){            this.callback = callback;        }        @Override        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {            super.onReceivedError(view, errorCode, description, failingUrl);            Message msg = new Message();            msg.what = errorCode;            msg.obj = description;            callback.handleMessage(msg);        }        @Override        public void onPageFinished(WebView view, String url) {            super.onPageFinished(view, url);            Message msg = new Message();            msg.what = STATE_FINISHED;            msg.obj = "finished";            callback.handleMessage(msg);        }        @Override        public void onPageStarted(WebView view, String url, Bitmap favicon) {            super.onPageStarted(view, url, favicon);            Message msg = new Message();            msg.what = STATE_STARTING;            msg.obj = "finished";            callback.handleMessage(msg);        }    }    private static class JsEngineChromeClient extends WebChromeClient{        public Handler.Callback callback;        public JsEngineChromeClient(Handler.Callback callback){            this.callback = callback;        }        @Override        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {            if (consoleMessage.messageLevel()==ConsoleMessage.MessageLevel.ERROR)            {                Log.e("JavaScriptManager" + consoleMessage.lineNumber(), consoleMessage.message());            }else if(consoleMessage.messageLevel()==ConsoleMessage.MessageLevel.WARNING){                Log.w("JavaScriptManager"+consoleMessage.lineNumber(),consoleMessage.message());            }else{                Log.i("JavaScriptManager"+consoleMessage.lineNumber(),consoleMessage.message());            }            return super.onConsoleMessage(consoleMessage);        }        @Override        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {            result.confirm();            Message msg = new Message();            try {                JSONObject json = new JSONObject(message);                msg.what = json.optInt("code",STATE_RESULT_OK);                msg.obj = json.optString("result","");            } catch (JSONException e) {                e.printStackTrace();                msg.what = STATE_RESULT_FAILED;            }            callback.handleMessage(msg);            return true;        }    }}

当然,我们还需要初始化,以保证我们的脚本可以更加健壮

public class ScriptFactory {    public String createScript()    {        StringBuilder sb = new StringBuilder();        sb.append("");        sb.append("\r\n");        sb.append("");        sb.append("\r\n");        sb.append("");        sb.append("\r\n");        sb.append("
");        sb.append("\r\n");        sb.append("
");        sb.append("\r\n");        sb.append("
Javascript Engine");        sb.append("\r\n");        sb.append("");        sb.append("\r\n");        sb.append("");        sb.append("\r\n");        sb.append("
");        sb.append("\r\n");        sb.append("window.handleEval = function( s)");        sb.append("\r\n");        sb.append("{");        sb.append("\r\n");        sb.append(" try{");        sb.append("\r\n");        sb.append("      var result = window.eval(s);   ");        sb.append("\r\n");        sb.append("      var ret = {code:100,result:result};   ");        sb.append("\r\n");        sb.append("      alert(JSON.stringify(ret));   ");        sb.append("\r\n");        sb.append("     }");        sb.append("\r\n");        sb.append("     catch(e)");        sb.append("\r\n");        sb.append("     {");        sb.append("\r\n");        sb.append("       var ret = {code:-100,result:'Express Error['+s+']==>'+e.message};  ");        sb.append("\r\n");        sb.append("       alert(JSON.stringify(ret));   ");        sb.append("\r\n");        sb.append("     }");        sb.append("\r\n");        sb.append("}");        sb.append("\r\n");        sb.append("");        sb.append("\r\n");        sb.append("");        sb.append("\r\n");        sb.append("");        return sb.toString();    }}

转载于:https://my.oschina.net/ososchina/blog/610964

你可能感兴趣的文章
测试工作的重要性和合作性
查看>>
我的友情链接
查看>>
常用服务器SSL证书安装方法大全
查看>>
mysql的主从复制,从库设为只读不能写
查看>>
linux使用mount挂载windows共享盘
查看>>
电脑盘符找不到找到文件的方法
查看>>
vSphere虚拟化之外部存储部署(下)
查看>>
云计算网络基础第六天
查看>>
Linux运维都要会哪些shell编程技能?
查看>>
把特斯拉送上火星的程序员,马斯克!
查看>>
git--客户端管理工具初步使用
查看>>
阿里的面试官都喜欢问哪些技术问题?
查看>>
基于curl 的zabbix API调用
查看>>
data guard 的部署
查看>>
oracle hints的那点事
查看>>
U盘拒绝访问怎么办?
查看>>
多网卡team,聚合连接(链路聚合)
查看>>
sublime text 3解放鼠标的快捷键总结
查看>>
我的友情链接
查看>>
Nessus HomeFeed 无法申请注册码解决办法
查看>>