0


android webview与H5页面交互 js调用原生代码回调原理

Android调用js代码:

webview.loadUrl("javascript:fun()")

js调用java代码:

getSettings().setJavaScriptEnabled(true);addJavascriptInterface(newJsHandel(),"jsApi");publicclassJsHandel{@JavascriptInterfacepublicvoidcall(String dataObj){}}
 不过这种只能简单的相互调用而已,如果需要回调(例如:js调用android方法并从android端返回数据)还需要做一定的封装处理才可以,大概实现步骤:
  1. 在android代码中向H5页面注入js对象
  2. js端创建一个存储callback回调函数唯一id、callback回调函数的map键值对对象,当js调用android代码时,生成一个callback回调函数唯一id,把该callback回调函数的唯一id和callback回调函数存放到map对象中,并把callback回调函数唯一id传递给android端
   3. android端执行js调用并获取到callback回调函数唯一id,调用js代码将执行结果数据和callback回调函数唯一id传递给js端
  4. js端遍历map对象并根据回调函数唯一id找到对应的callback回调函数,通过callback.call(null, data)执行该js回到函数

 至此js调用android代码并完成回调,具体代码如下:
  1. 在android代码中向H5页面注入js对象
//MainActivity.java@OverridepublicvoidinitView(){
        binding.webview.registHandel("gjsbridgeApi",newJsHandel(){@Overridepublicvoidjscall(String funName,String funData,JsFunctionCallBack jsFunction){if("getVolumn".equals(funName)){VolumnApi volumnApi =newVolumnApi();
                    jsFunction.callback(volumnApi.getVolumn(MainActivity.this));return;}elseif("showToast".equals(funName)&& funData!=null&&!funData.isEmpty()){Toast.makeText(MainActivity.this, funData,Toast.LENGTH_LONG).show();return;}
                jsFunction.callback("from native");}});
        binding.webview.loadUrl("http://pojul.gitee.io/web/testjsbridge/");}//GjsbridgeWebview.javapublicvoidregistHandel(String handelName,JsHandel jsHandel){if(jsHandel==null){return;}
        jsHandel.init(this);getSettings().setJavaScriptEnabled(true);addJavascriptInterface(jsHandel, handelName);}//JsHandel.javapublicabstractclassJsHandel{privatestaticfinalString TAG ="JsHandel";privateGjsbridgeWebview gjsbridgeWebview;publicvoidinit(GjsbridgeWebview gjsbridgeWebview){this.gjsbridgeWebview = gjsbridgeWebview;}@JavascriptInterfacepublicvoidcall(String dataObj){JsFun jsFun =newGson().fromJson(dataObj,JsFun.class);if(jsFun.funName==null||jsFun.funName.isEmpty()){return;}JsFunctionCallBack jsFunction =newJsFunctionCallBack(jsFun.funId){@Overridepublicvoidcallback(String respData){if(gjsbridgeWebview==null){Log.e(TAG,"gjsbridgeWebview has not init");return;}if(funId==null||funId.isEmpty()){return;}
                gjsbridgeWebview.post(()->{
                    gjsbridgeWebview.loadUrl("javascript:gjsbridgeApiCallBack('"+funId+"', '"+respData+"')");});}};jscall(jsFun.funName, jsFun.funData, jsFunction);}publicabstractvoidjscall(String funName,String funData,JsFunctionCallBack jsFunction);}//JsFun.javapublicclassJsFun{publicString funId;publicString funName;publicString funData;}
  1. js端创建map并执行callback.call(null, data)代码
//api.jsclassApi{constructor(){}showToast(msg){call("showToast", msg,null);}getVolumn(fun){call("getVolumn",null, fun);}}var api =newApi();var funMap =newMap();functiongjsbridgeApiCallBack(funId, data){
    console.log("H5 gjsbridgeApiCallBack funId: "+ funId +"; data: "+ data);let fun = funMap.get(funId);if(fun!=null){fun.call(null, data);}
    funMap.delete(funId);
    console.log("funMap size: "+ funMap.size)}functioncall(name, data, fun){if(window.gjsbridgeApi==null){
        console.log(name +"; H5 window.gjsbridgeApi: null");}else{
        console.log(name +"; H5 window.gjsbridgeApi: "+ window.gjsbridgeApi);let dataObj ={funName: name,funData: data
        }if(fun!=null&&typeof fun ==="function"){let funId = Date.now()+"";
            funMap.set(funId, fun);
            dataObj.funId = funId;}
        window.gjsbridgeApi.call(JSON.stringify(dataObj));}}
  1. H5直接调用
//test.html<body><div class="toast-div" id="show" onclick="showToast()">toast</div><div class="toast-div" id="volumn" onclick="getVolumn()">volumn: unknow</div></body><script type="text/javascript">functionshowToast(){
            api.showToast("toast-div click");}functiongetVolumn(){
            api.getVolumn(function(data){
                console.log("getVolumn: "+ data);
                document.getElementById("volumn").innerHTML = data;});}</script>

demo地址: https://github.com/pojul/gjsbridge:
gjsbridge集成:implementation ‘io.github.pojul:gjsbridge:1.0.1’


本文转载自: https://blog.csdn.net/github_36165539/article/details/126581220
版权归原作者 github_36165539 所有, 如有侵权,请联系我们删除。

“android webview与H5页面交互 js调用原生代码回调原理”的评论:

还没有评论