美文网首页小诗
Android和js相互调用的方式总结

Android和js相互调用的方式总结

作者: breaktian | 来源:发表于2018-09-04 00:41 被阅读124次

    js调用Android原生:

    声明@JavascriptInterface,进行对象映射

    android:

    myWebView = (WebView) findViewById(R.id.webview);
    myWebView .getSettings().setJavaScriptEnabled(true);
    myWebView .addJavascriptInterface(new JavaScriptInterface(this),"android");
    
    public class JavaScriptInterface{
      Context context;
      public JavaScriptInterface(Context c){
        context = c;
      }
      //与js交互时用到的方法
      @JavascriptInterface
      public void showToast(String ssss){
        // todo
      }
    }
    

    js:

    <script type="text/javascript">
      function showText(){
        android.showToast("hello world");
      }
    <script>
    </head>
    <body>
    <input type="button" value="调用" onClick="showToast()" />
    
    </body>
    
    
    2. shouldOverrideUrlLoading

    android:

     class InnerWebViewClient extends WebViewClient {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                showProgress();
            }
    
            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                if (Macro.isDebug) {
                    handler.proceed();
                } else {
                    super.onReceivedSslError(view, handler, error);
                }
            }
    
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                L.e(url);
                if (!TextUtils.isEmpty(url) && url.startsWith(CallBackUrl.MOVE)) {//迁移
                    Uri uri = Uri.parse(url);
                    String token = uri.getQueryParameter("_tk");
                    if (TextUtils.isEmpty(token)) {
                        token = uri.getQueryParameter("portal_token");
                    }
                    Intent intent = new Intent();
                    intent.putExtra(Result.EXTRA_TOKEN, token);
                    setResult(RESULT_OK, intent);
                    finish();
                    return true;
                }else if (!TextUtils.isEmpty(url) && url.startsWith(CallBackUrl.FORGET_PWD)){//忘记密码
                    Uri uri = Uri.parse(url);
                    String token = uri.getQueryParameter("_tk");
                    if (TextUtils.isEmpty(token)) {
                        token = uri.getQueryParameter("portal_token");
                    }
                    Intent intent = new Intent();
                    intent.putExtra(Result.EXTRA_TOKEN, token);
                    setResult(RESULT_OK, intent);
                    finish();
                    return true;
                }else if (!TextUtils.isEmpty(url) && url.startsWith(CallBackUrl.PWD_SET)){//设置支密
                    Uri uri = Uri.parse(url);
                    String token = uri.getQueryParameter("_tk");
                    if (TextUtils.isEmpty(token)) {
                        token = uri.getQueryParameter("portal_token");
                    }
                    Intent intent = new Intent();
                    intent.putExtra(Result.EXTRA_TOKEN, token);
                    setResult(RESULT_OK, intent);
                    finish();
                    return true;
                }
                return super.shouldOverrideUrlLoading(view, url);
            }
        }
    

    js:

    window.location.href="http://www.baidu.com"
    
    3.使用WebChromeClient.onConsoleMessage函数

    android:

    public class CustomWebChromeClient extends WebChromeClient{
      @Override
      public boolean onConsoleMessage(ConsoleMessage consoleMessage){
        super.onConsoleMessage(consoleMessage);
        String msg = consoleMessage.message();//log内容
      }
    }
    

    js:

    console.log("log message that is going to native code");
    
    4.使用WebChromeClient.onJsPrompt函数,拦截JS输入框消息

    android:

    public class CustomWebChromeClient extends WebChromeClient{
      @Override
      public boolean onJsPromt(Webview view, String url, String message,String defaultValue,JsPromptResult result){
        //处理JS 的调用逻辑
        result.confirm();
        return true;
      }
    }
    

    js:

    window.prompt(message,value)
    
    三种方法对比
    调用方式 优点 缺点 使用场景
    @JavascriptInterface 方便简洁 Android4.2以下存在任意代码执行漏洞 Android4.2以上相对简单互调场景
    shouldOverrideUrlLoading 不存在漏洞问题 使用复杂,需要进行协议的约束;从Native层往Web层传递值比较繁琐 不需要返回值情况下的互调场景
    onJsPrompt 不存在漏洞问题 使用复杂,需要进行协议的约束 能满足大多数情况下的互调场景

    Android调用JS原生代码方法

    1.Webview.loadUrl()

    android:

    //必须在新开的线程中调用,否则无法调用
    mWebview.post(new Runable(){
        @Override
        public void run(){
          mWebview.load("javascript:callJS()");
        }
      }
    
    );
    

    js:

    //Android需要调用的方法
    function callJS(){
      alert("Android调用了JSde callJS方法");
    }
    
    2. Webview.evaluateJavascript
    • 该方法执行不回使页面刷新,loadUrl会刷新页面
    • Android4.4之后才能使用
      android:
    mWebview.evaluateJavascript ("javascript:callJS()", new ValueCallback<String>(){
      @Override
      public void onReceiveValue(String value){
        //此处为js返回的结果
      }
    })
    

    方法对比:

    调用方式 优点 缺点 使用场景
    使用loadUrl 方便简洁 效率低;获取返回值麻烦 不需要获取返回值,对性能要求较低时
    使用evaluateJavascript 效率高 向下兼容性差(仅Android 4.4 以上可用) Android 4.4以上

    相关文章

      网友评论

        本文标题:Android和js相互调用的方式总结

        本文链接:https://www.haomeiwen.com/subject/toswwftx.html