写在前面

本来想做 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();
      }
  }
}

JS 代码

function validate() {
    var msg = msgInput.value.trim();
    if (msg == "") {
        javascript:jsInterFace.showToast("EMPTY_INPUT");
        return false;
    }
    return true;
}

Android 调用 JS

  • 只执行方法可以使用

    mChatWV.loadUrl("javascript:initData('" + JSON.toJSONString(paramsMap) + "', '" + userTokens[0] + "', '" + userTokens[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 的加载速度很慢,不建议使用

参考文章

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

标签: none

添加新评论