做汽车新闻哪个网站好网推项目平台

JSAPI的技术原理图
H5和Java通信
H5要想和Java通信,Java需要通过WebView往H5里面注入一个JavaObj,之后JS就可以通过这个JavaObj对象其提供带@JavascriptInterface注解的方法
//注册js对象,名字叫nativeObj,可以在JS里面引用这个名字,来调用JsBridge对象的带@JavascriptInterface注解的public方法mWebView.addJavascriptInterface(new JsBridge(this,mWebView),"nativeObj");JS代码示例
Java和H5通信
Java可以通过mWebView.loadUrl("javascript:handleMsgFromNative('" + json + "')")来执行JS函数,不过这个loadUrl()函数没法接收JS函数的返回值,如果我们想接收JS函数的返回值,我们可以使用
mWebView.evaluateJavascript("handleMsgFromNative('" + json + "')", new ValueCallback() { @Override public void onReceiveValue(String value) { System.out.println("value="+value); }});
Java和H5双向通信注意事项
H5调Java对象的方法,实际上Java对象的方法并不是运行在主线程中,而是运行在一个名叫JavaBridge的工作线程中,所以我们在开发JSAPI的时候,要注意线程间的切换。
Java调用H5里面的JS函数,必须要在主线程中调用,否则会出现错误。
JsBridge类
在JSAPI模块开发过程中,我们一般不会为每一个JSAPI都提供一个java类方法,通常我们会采用桥接模式对这个接口进行封装,让我们的具体JSAPI的开发更加灵活方便,下面是我写的一个简单的JsBridge封装类,大家可以参考一下
/** * js和native双向通信的bridge类 * author: kgdwbb * date:2020-04-18 */public class JsBridge { private Activity mActivity; private WebView mWebView; public JsBridge(Activity activity,WebView webView) { mActivity=activity; mWebView = webView; } @JavascriptInterface public void helloJava(String msg) { System.out.println(msg); } @JavascriptInterface public void handleMsgFromJs(String json) { String tname = Thread.currentThread().getName(); //注意:js调native的方法,不是运行在主线程,而是运行在JavaBridge线程 System.out.println("tname="+tname); RequestModel model = JSONObject.parseObject(json,RequestModel.class); JsCallback jsCallback = new JsCallback(mActivity,mWebView); //注意:这里是一些示例代码,涉及到具体的业务,大家可以在这个基础上继续封装 if ("hello".equals(model.name)) { //取出js传递给native的content参数 String content = model.params.get("content").toString(); //把content数据输出,这只是示例,大家可以根据业务需要,进行相应的处理 System.out.println("content=" + content); ArrayMap resultMap=new ArrayMap<>(); resultMap.put("content","hello js"); //jsapi业务处理完成后,把对应的处理结果返回给js sendCallback(jsCallback,model.callbackId,0,"",resultMap); } else { sendCallback(jsCallback,model.callbackId,-1,"jsapi not exist",null); } } /** * 把natvie的处理结果返回给js * @param jsCallback jsCallback对象 * @param callbackId js传给native的callbackId * @param errCode 错误码 * @param errMsg 错误信息 * @param resultMap native返回给js的结果 */ private void sendCallback(JsCallback jsCallback, String callbackId, int errCode, String errMsg, ArrayMap resultMap) { ResultModel result = new ResultModel(errCode, errMsg); result.result = resultMap; ResponseModel response = new ResponseModel(); response.callbackId = callbackId; response.response = result; jsCallback.callback(response); } public static class RequestModel { /** * jsapi的名字 */ public String name; /** * JS动态生成的全局唯一的callback id,Native通过这个callbackId异步的把JS调用Native的返回结果返回给JS */ public String callbackId; /** * jsapi的参数 */ public ArrayMap params; } public static class ResponseModel { /** * JS动态生成的全局唯一的callback id,Native通过这个callbackId异步的把JS调用Native的返回结果返回给JS */ public String callbackId; /** * jsapi的返回值包装类 */ public ResultModel response; } public static class ResultModel { public ResultModel(int errCode, String errMsg) { this.errCode = errCode; this.errMsg = errMsg; } /** * 错误码 */ public int errCode; /** * 错误信息 */ public String errMsg; /** * jsapi调用成功的返回值 */ public ArrayMap result; } public static class JsCallback { private WeakReference mActivity; private WeakReference mWebView; public JsCallback(Activity activity,WebView webView) { mActivity = new WeakReference<>(activity); mWebView = new WeakReference<>(webView); } /** * native把jsapi的返回值返回给js * * @param model */ public void callback(final ResponseModel model) { if (mWebView.get() != null) { //注意:这里一定要做线程上下文切换,因为当前线程是JavaBridge线程,不是主线程,webview必须在主线程中才能调JS函数 mActivity.get().runOnUiThread(new Runnable() { @Override public void run() { String json = JSONObject.toJSONString(model); mWebView.get().loadUrl("javascript:handleMsgFromNative('" + json + "')"); } }); } } }}