天天看点

Android hybrid 开发实践(android webview)

关于Android 和 h5 hybrid 开发的实践在网上有很多,Android自身就有一个webview,很多实践都是通过webview来实现的,以下是记录一下自己的实践。

1、Android与H5通讯方式

主要有两种:有基于url拦截的,也有基于prompt拦截的。 Android上面最火的这个开源项目 JsBridge就是基于url来进行拦截的

2、JsBridge原理和用法

原理 Android调用H5:通过webview类的loadUrl方法可以直接执行js代码,类似浏览器地址栏输入一段js一样的效果

webview.loadUrl("javascript: alert('hello world')");
           

H5调用Android:webview可以拦截H5发起的任意url请求,webview通过约定的规则对拦截到的url进行处理(消费),即可实现H5调用Android

var ifm = document.createElement('iframe');
ifm.src = 'jsbridge://namespace.method?[...args]';
           

JsBridge上面已经封装了一层协议了,关于协议的设置我们之前有这篇文章Android自定义UrlSchema。所以如果要自定义一套协议的话,可以参考下面这个方式

schema://classname/method?value={} // Android会收到这个url
           

schema即自行约定的私有协议,一般是公司名或者应用名

classname/method这两个一起,指定API名称,classname可以是Android的类名,当然也可以只是一个普通字符串(如namespace),只要Android方便识别即可

value是与method对应的参数

请求示例:

// H5直接指定包名和方法名,这样更容易扩展
iframe.src = `myschema://com.mycompany.hybrid.InteractHandler/toast?value={msg: 'hello world'}`

// 用约定的字符串也可以,Android拿到之后自己再做一次map
iframe.src = `myschema://interact/toast?value={msg: 'hello world'}
           

JsBridge用法1:

java注册handler方法以供h5里面的js调用

webView.registerHandler("submitFromWeb", new BridgeHandler() {
        @Override
        public void handler(String data, CallBackFunction function) {
            Log.i(TAG, "handler = submitFromWeb, data from web = " + data);
            function.onCallBack("submitFromWeb exe, response data from Java");
        }
    });
           

js可以通过下面的方式调用这个的java handler的“submitFromWeb”方法

WebViewJavascriptBridge.callHandler(
        'submitFromWeb'
        , {'param': str1}
        , function(responseData) {
            document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
        }
    );
           

JsBridge用法2:

js注册handler方法以供Java里面的代码调用

WebViewJavascriptBridge.registerHandler("functionInJs", function(data, responseCallback) {
        document.getElementById("show").innerHTML = ("data from Java: = " + data);
        var responseData = "Javascript Says Right back aka!";
        responseCallback(responseData);
    });
           

java里面可以通过以下方式来调用这个js handler的“functionInJs"方法

webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {
        @Override
        public void onCallBack(String data) {

        }
    });
           

3、使用过程中的问题

1、最主要有一个是性能问题,通过iframe的src来进行跳转会遇到加载慢的问题,存在js已经加载完了,但是bridge还没有ready的情况,以至于有些情况下前端任务这个时间差太长了

2、是否存在jsbridge加载失败,可以通过cookiemanager传递一些内容?

3、用户信息的传递,通过token来传递

4、js中如何加上权限控制?java中如何控制js中代码的权限? 参考各种h5类型的开放平台实现

4、结语

性能问题可以考虑不采用url方式,而采用promt方式来实现?