JSbridge系列解析(一):JS-Native调用方法

JSBrige系列直通车,由浅入深理解JS-Native的通信过程:
JSbridge系列解析(一):JS-Native调用方法
JSbridge系列解析(二):lzyzsd/JsBridge使用方法
JSbridge系列解析(三):lzyzsd/JsBridge源码解析
JSbridge系列解析(四):Web端发消息给Native代码流程具体分析

web具有开发速度快,上线方便等优点;而native开发则展示效果好,但开发节奏慢。在开发中,经常需要将web开发和native开发相结合,这就需要了解JS和Native之间相互调用的方法了。

基本知识

安卓提供Webview用来加载html页面,以安卓4.4系统为分水岭,之前的webview内核采用webkit;4.4及之后改为chromium内核。

JS -> Native

常用的JS调用Java代码的方法,主要包括以下三种:
1)通过WebView的addJavascriptInterface进行对象映射
2)通过 WebViewClient 的shouldOverrideUrlLoading方法回调拦截 url
3) 通过 WebChromeClient 的onJsAlert、onJsConfirm、onJsPrompt方法回调拦截JS对话框alert、confirm、prompt 消息

今天主要介绍第一种,也是最常用的使用方案。首先需要打开WebView的一个设置选项。如下:

//允许运行js代码
mWebView.getSettings().setJavaScriptEnabled(true); 

WebView提供addJavascriptInterface方法,用于注入Java函数以便JS调用。示例如下:

/**
This method can be used to allow JavaScript to control the host application. This is a powerful feature, but also presents a security risk for applications targeted to API level [JELLY_BEAN](http://developer.android.com/reference/android/os/Build.VERSION_CODES.html#JELLY_BEAN)
 or below, because JavaScript could use reflection to access an injected object's public fields. Use of this method in a WebView containing untrusted content could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using this method in a WebView which could contain untrusted content.
JavaScript interacts with Java object on a private, background thread of this WebView. Care is therefore required to maintain thread safety.
The Java object's fields are not accessible
*/
//注入js对象jsInterface
mWebView.addJavascriptInterface(new JSInterface(), "jsInterface");  

根据安卓官方的api说明,addJavaScriptInterface方法存在安全漏洞。因为JS可以通过反射访问注入对象。官方在4.2及以后的系统中修复了该问题,要求注入的远程方法必须使用注解@JavascriptInterface

//JAVA代码
class JsObject {  
   @JavascriptInterface  
   public String toString() { return "injectedObject"; }  
}  
webView.addJavascriptInterface(new JsObject(), "injectedObject");  

//JS调用注入对象示例【java代码】
webView.loadUrl("javascript:alert(injectedObject.toString())");  

针对4.2以下的系统,可以利用JS的事件来解决,如prompt, alert等。这样的动作都会对应到WebChromeClient类中相应的方法,对于prompt,它对应的方法是onJsPrompt方法,这个方法的声明如下:

public boolean onJsPrompt(WebView view, String url, String message,   
    String defaultValue, JsPromptResult result)  

prompt方案可参考PhoneGap的实现,主要包括以下几点
【1】在4.2以下系统,js对象未注入的情况下,可让JS调用prompt方法,通过prompt把JS中的信息传递到Java部分。这些信息应该是我们定义的一段有特定含义的文本,可能包含:特定标识,方法名称,参数等。在onJsPrompt方法中,我们去解析传递过来的文本,得到方法名,参数等,再通过反射机制,调用指定的方法,从而调用到Java对象的方法。
【2】关于返回值,可以通过prompt返回回去,这样就可以把Java中方法的处理结果返回到Js中。
【3】我们需要动态注入一段JavaScript初始化的脚本,可通过webview的loadUrl来加载,从而注册到html页面中。如PhoneGap中的js文件

注意:1)注入JS方法不能过早,一般在onPageFinished方法,否则注入可能无效
2)在Android 3.0以下,安卓系统添加了一个名为searchBoxJavaBridge_的Js接口,需要调用removeJavascriptInterface方法删除该方法,以解决安全风险。
3)记忆中在4.4系统之前,onJsPrompt运行在主线程中;而4.4及以后,该方法运行在非主线程。请各位看客验证

Native -> JS

Java调用JS的方法,包括以下两种:
1)通过WebView的loadUrl方法,该方法必须在主线程中调用
2)通过WebView的evaluateJavascript,该方法可获取JS返回值,但4.4及以上才能使用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容