Android WebView与H5交互汇总
Posted dfqin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android WebView与H5交互汇总相关的知识,希望对你有一定的参考价值。
目前APP中内嵌Web页面非常常见,为了Web网页可以和原生进行交互,需要设计一套js-bridge,而这个桥接的设计底层都还是依赖系统提供的Webview与H5的交互,现有交互方式汇总如下:
1、原生调用JS
原生调用JS即在原生代码中调用执行当前网页中js代码,现有两种方法
1)WebView#loadUrl("javascript:func('" + arg + "')")
2) WebView#evaluateJavascript(String script, @Nullable ValueCallback<String> resultCallback)
其中第二种方法,从android4.4版本才支持,两种方法比较起来,也是第二种方法优于第一种方法:
1)第二种方法执行效率比第一种方法高
2)第一种方法会触发页面刷新,第二种方法不会触发页面刷新
3)第二种方法可以直接获取js函数执行的返回值,而第一种想要获取返回值比较麻烦,需要设计一套机制,通过JS调用原生的方式把返回值传递过来
2、H5调用原生
即H5主动调用原生代码,可以执行原生函数或者获取原生返回的数据,通常有3中方法:
1)WebView#addJavascriptInterface(Object object, String name) 进行对象映射
2)WebViewClient#shouldOverrideUrlLoading() 来拦截Url调用代码
3)WebChromeClient 的 onJsAlert()、onJsConfirm()、
onJsPrompt() 拦截 js 中的对话框 alert() / confirm() / prompt()
实际上第一种方法是官方提供的H5调用原生的方法,后面两种是利用官方API规则自己模拟实现了H5调用原生的方法。
第一种方法类似于注入一个JS对象到H5页面中,而这个JS对象映射到了一个JAVA对象,在H5中直接调用这个JS对象的方法就可以调用到AVA对象,它的效率也是比较高的。但是因为这个设计在4.2以前的版本有安全漏洞,所以之前很多人放弃了这种调用方式。漏洞在4.2的版本解决了,简单讲就是供JS调用的方法添加注解@JavascriptInterface即可。
第二种第三种本质是一样的,拿第二种举例,在H5端发起页面跳转时,首先会被原生的shouldOverrideUrlLoading()函数拦截并决定是否进行跳转,那么我们可以约定一个特定格式的URL,当拦截到跳转发现是这种格式的URL,我们可以认为这是一个H5发起的桥接调用,我们解析执行原生代码,不进行跳转。例如拦截到的URL格式为:myapp://getuser?param=xxxxx,我们可以认为myapp开头的就是我们约定的桥接函数,后面的getuser是函数名,需要的入参和返回值回调函数通过param的值获取。这种拦截的方式实现,把原生的值返回给H5比较麻烦,通常的实现思路是在H5中给回调函数制定一个编号,原生通过上面原生调用H5的方法调用H5的处理函数,把回调函数编号和结果传递过去,再由H5的处理函数执行回调函数。
以上是关于Android WebView与H5交互汇总的主要内容,如果未能解决你的问题,请参考以下文章