小诗

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

2018-09-04  本文已影响124人  breaktian

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
mWebview.evaluateJavascript ("javascript:callJS()", new ValueCallback<String>(){
  @Override
  public void onReceiveValue(String value){
    //此处为js返回的结果
  }
})

方法对比:

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

猜你喜欢

热点阅读