h5与native交互总结1

Android AUmaWSsSoi 1个月前 (04-13) 73次浏览 0个评论
文章目录[隐藏]

1. 常见的通讯方案

在这里我们讨论的是Android平台,js与native通讯主要包括Java调Js,Js调Java; Java调Js主要是通过webView.loadUrl(url)来实现,Js调Java包括两种;一种是Android原生支持的addJavascriptInterface(),另一种就是JsBridge.

2. jsBridge

这里我们主要讨论的是jsBridge,jsBridge不同的开源项目实现的方式还是有些细微的差别的

3. safe-java-js-webview-bridge

这个方案存在很早了,但是作者已经很久都没有维护了,还是有不少缺陷的,我更新了工程的配置,重新做了下处理。
使用的时候只需要依赖

compile 'com.github.xingstarx:safe-java-js-webview-bridge:master-SNAPSHOT'

这个的实现思路如下:

  1. 生成需要嵌入到html里面js代码
  2. js调用Java方法的时候会回调WebChromeClient的onJsPrompt方法,这个时候会把关键的参数信息传递回来,对这些参数进行解析并执行,也就是执行jsCallJava.call(webView, jsonStr),在这个过程中,就通过反射的机制,执行了我们的java方法

贴一下格式化后的这段js代码:

javascript: (function(b) {
    console.log("HostApp initialization begin");
    var a = {
        queue: [],
        callback: function() {
            var d = Array.prototype.slice.call(arguments, 0);
            var c = d.shift();
            var e = d.shift();
            this.queue[c].apply(this, d);
            if (!e) {
                delete this.queue[c]
            }
        }
    };
    a.alert = a.changeVariables = a.retJavaObject = a.selectImage = a.toast = function() {
        var f = Array.prototype.slice.call(arguments, 0);
        if (f.length < 1) {
            throw "HostApp call error, message:miss method name"
        }
        var e = [];
        for (var h = 1; h < f.length; h++) {
            var c = f[h];
            var j = typeof c;
            e[e.length] = j;
            if (j == "function") {
                var d = a.queue.length;
                a.queue[d] = c;
                f[h] = d
            }
        }
        var g = JSON.parse(prompt(JSON.stringify({
            method: f.shift(),
            types: e,
            args: f
        })));
        if (g.code != 200) {
            throw "HostApp call error, code:" + g.code + ", message:" + g.result
        }
        return g.result
    };
    Object.getOwnPropertyNames(a).forEach(function(d) {
        var c = a[d];
        if (typeof c === "function" && d !== "callback") {
            a[d] = function() {
                return c.apply(a, [d].concat(Array.prototype.slice.call(arguments, 0)))
            }
        }
    });
    b.HostApp = a;
    console.log("HostApp initialization end")
})(window);

js学的不是很好,这段代码没看懂,好菜啊😭

4. 存在的缺陷,以及完善,对koltin的支持

github上面这个项目的issue不少,作者也没有在跟进了,问题比较多
另外项目用上了如今比较火的kotlin语言,那么实现的HostApp这个kotlin类无法正常工作,是由于koltin的语言特性造成,kotlin实现的类默认都是public final method()形式的

if (method.getModifiers() != (Modifier.PUBLIC | Modifier.STATIC) || (sign = genJavaMethodSign(method)) == null) {
                    continue;
                }

JsCallJava的构造方法里面有这么一段判断逻辑,规定了HostApp里面的类方法得是public static method(),而不能是其他的,所以对判断逻辑做了一点修改

//针对kotlin语言做兼容处理,kotlin实现的HostApp,是`pubic static final method()`,而java语言实现的HostApp是`public static method()`,仔细理解下面的位运算
if ((method.getModifiers() | Modifier.FINAL) != (Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL) || (sign = genJavaMethodSign(method)) == null) {
        continue;
  }

5. 其他的jsBridge方案

在github上找到了其他的jsBridge,还需要调研下在总结
JsBridge 有一段时间没有维护了
JsBridge 比较新


java问与答 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:http://javaexception.com/archives/16
喜欢 (1)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址