安卓与 JS 交互要注意的问题

... 2018-12-12 18:49 大约 2 分钟

本来想做 H5 的聊天嵌入到 Android 中,做到后面发现中间的数据交互很多,互相依赖性太强了,所以还是选择了用 Android 来做聊天,网上资料很多,记录一下以便查阅

# 代码部分

# Android 代码

WebSettings settings = mChatWV.getSettings();
settings.setJavaScriptEnabled(true); // 支持 JS
settings.setSupportZoom(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
    settings.setAllowUniversalAccessFromFileURLs(true);
}
mChatWV.addJavascriptInterface(new JsInterface(),"jsInterFace");
mChatWV.loadUrl("file:///android_asset/chat.html");
final Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("orderId", orderId);
paramsMap.put("baseUrl", com.box.common.Constants.WEB_SERVER_DOMAIN);
paramsMap.put("loadMoreTxt", getString(R.string.chat_click_load_more));
// 为了加载完 HTML 之后再调用 JS 方法,你的 JS 方法可以写在 onPageFinished 里面
mChatWV.setWebViewClient(new WebViewClient(){
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        String[] userTokens = userToken.split("\n");
        if(mChatWV != null) {
          // Android 调用 JS
            mChatWV.loadUrl("javascript:initData('" + JSON.toJSONString(paramsMap) + "', '" + userTokens[0] + "', '" + userTokens[1] + "')");
        }
    }
});

public class JsInterface{
  /**
    *  //在 JS 中调用 window.AndroidWebView.showToast(message) ,便会触发此方法弹出一个 Toast。
    * @param message JS 端需要传递的参数(也就是要 Toast 的内容)
    */
  @JavascriptInterface
  public void showToast(String message) {
      if (getContext() != null) {
          Toast.makeText(getContext(),message,Toast.LENGTH_LONG).show();
      }
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# JS 代码

function validate() {
    var msg = msgInput.value.trim();
    if (msg == "") {
        javascript:jsInterFace.showToast("EMPTY_INPUT");
        return false;
    }
    return true;
}
1
2
3
4
5
6
7
8

# Android 调用 JS

  • 只执行方法可以使用
    mChatWV.loadUrl("javascript:initData('" + JSON.toJSONString(paramsMap) + "', '" + userTokens[0] + "', '" + userTokens[1] + "')");
    
    1
  • 需要获取返回值(根据 Android 版本不同有所区分)

# JS 调用 Android

  • 只执行方法可以使用 javascript:jsInterFace.showToast(message);
  • 需要获取返回值要用 window.jsInterFace.getData()
    • 例如: var status = window.jsInterFace.checkOrderStatus(currentStatus).toLocaleString();

# 需要注意的问题

  1. JS 调用 Android 效率更高,推荐更多使用 JSAndroid
  2. Js 调用 Android 的方法、返回值如果是字符串、你会发现这个字符串是 native 的、转成 locale 的才能正常使用、使用 toLocaleString() 函数就可以了、不过这个函数的速度并不快、转化的字符串如果很多、将会很耗费时间
  3. 使用 jQuery 的加载速度很慢,不建议使用

# 参考文章

本文只是小白开发过程中的整理,参考了不少其他人写的文章,以下参考不分先后

上次编辑于: 2021年5月27日 20:21