JSbridge系列解析(一):JS-Native調(diào)用方法

JSBrige系列直通車,由淺入深理解JS-Native的通信過程:
JSbridge系列解析(一):JS-Native調(diào)用方法
JSbridge系列解析(二):lzyzsd/JsBridge使用方法
JSbridge系列解析(三):lzyzsd/JsBridge源碼解析
JSbridge系列解析(四):Web端發(fā)消息給Native代碼流程具體分析

web具有開發(fā)速度快扣甲,上線方便等優(yōu)點(diǎn)恼除;而native開發(fā)則展示效果好细诸,但開發(fā)節(jié)奏慢园爷。在開發(fā)中镜会,經(jīng)常需要將web開發(fā)和native開發(fā)相結(jié)合巾陕,這就需要了解JS和Native之間相互調(diào)用的方法了魂奥。

基本知識(shí)

安卓提供Webview用來加載html頁面菠剩,以安卓4.4系統(tǒng)為分水嶺,之前的webview內(nèi)核采用webkit耻煤;4.4及之后改為chromium內(nèi)核具壮。

JS -> Native

常用的JS調(diào)用Java代碼的方法,主要包括以下三種:
1)通過WebView的addJavascriptInterface進(jìn)行對(duì)象映射
2)通過 WebViewClient 的shouldOverrideUrlLoading方法回調(diào)攔截 url
3) 通過 WebChromeClient 的onJsAlert哈蝇、onJsConfirm棺妓、onJsPrompt方法回調(diào)攔截JS對(duì)話框alert、confirm炮赦、prompt 消息

今天主要介紹第一種怜跑,也是最常用的使用方案。首先需要打開WebView的一個(gè)設(shè)置選項(xiàng)吠勘。如下:

//允許運(yùn)行js代碼
mWebView.getSettings().setJavaScriptEnabled(true); 

WebView提供addJavascriptInterface方法性芬,用于注入Java函數(shù)以便JS調(diào)用。示例如下:

/**
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對(duì)象jsInterface
mWebView.addJavascriptInterface(new JSInterface(), "jsInterface");  

根據(jù)安卓官方的api說明看幼,addJavaScriptInterface方法存在安全漏洞批旺。因?yàn)镴S可以通過反射訪問注入對(duì)象。官方在4.2及以后的系統(tǒng)中修復(fù)了該問題诵姜,要求注入的遠(yuǎn)程方法必須使用注解@JavascriptInterface

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

//JS調(diào)用注入對(duì)象示例【java代碼】
webView.loadUrl("javascript:alert(injectedObject.toString())");  

針對(duì)4.2以下的系統(tǒng)汽煮,可以利用JS的事件來解決,如prompt, alert等棚唆。這樣的動(dòng)作都會(huì)對(duì)應(yīng)到WebChromeClient類中相應(yīng)的方法暇赤,對(duì)于prompt,它對(duì)應(yīng)的方法是onJsPrompt方法宵凌,這個(gè)方法的聲明如下:

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

prompt方案可參考PhoneGap的實(shí)現(xiàn)鞋囊,主要包括以下幾點(diǎn)
【1】在4.2以下系統(tǒng),js對(duì)象未注入的情況下瞎惫,可讓JS調(diào)用prompt方法溜腐,通過prompt把JS中的信息傳遞到Java部分。這些信息應(yīng)該是我們定義的一段有特定含義的文本瓜喇,可能包含:特定標(biāo)識(shí)挺益,方法名稱,參數(shù)等乘寒。在onJsPrompt方法中望众,我們?nèi)ソ馕鰝鬟f過來的文本,得到方法名,參數(shù)等烂翰,再通過反射機(jī)制夯缺,調(diào)用指定的方法,從而調(diào)用到Java對(duì)象的方法甘耿。
【2】關(guān)于返回值踊兜,可以通過prompt返回回去,這樣就可以把Java中方法的處理結(jié)果返回到Js中棵里。
【3】我們需要?jiǎng)討B(tài)注入一段JavaScript初始化的腳本润文,可通過webview的loadUrl來加載,從而注冊(cè)到html頁面中殿怜。如PhoneGap中的js文件

注意:1)注入JS方法不能過早典蝌,一般在onPageFinished方法,否則注入可能無效
2)在Android 3.0以下头谜,安卓系統(tǒng)添加了一個(gè)名為searchBoxJavaBridge_的Js接口骏掀,需要調(diào)用removeJavascriptInterface方法刪除該方法,以解決安全風(fēng)險(xiǎn)柱告。
3)記憶中在4.4系統(tǒng)之前截驮,onJsPrompt運(yùn)行在主線程中;而4.4及以后际度,該方法運(yùn)行在非主線程葵袭。請(qǐng)各位看客驗(yàn)證

Native -> JS

Java調(diào)用JS的方法,包括以下兩種:
1)通過WebView的loadUrl方法乖菱,該方法必須在主線程中調(diào)用
2)通過WebView的evaluateJavascript坡锡,該方法可獲取JS返回值,但4.4及以上才能使用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末窒所,一起剝皮案震驚了整個(gè)濱河市鹉勒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吵取,老刑警劉巖禽额,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異皮官,居然都是意外死亡脯倒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門捺氢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盔憨,“玉大人,你說我怎么就攤上這事讯沈。” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵缺狠,是天一觀的道長问慎。 經(jīng)常有香客問我,道長挤茄,這世上最難降的妖魔是什么如叼? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮穷劈,結(jié)果婚禮上笼恰,老公的妹妹穿的比我還像新娘。我一直安慰自己歇终,他們只是感情好社证,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著评凝,像睡著了一般追葡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奕短,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天宜肉,我揣著相機(jī)與錄音,去河邊找鬼翎碑。 笑死谬返,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的日杈。 我是一名探鬼主播遣铝,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼达椰!你這毒婦竟也來了翰蠢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬榮一對(duì)情侶失蹤啰劲,失蹤者是張志新(化名)和其女友劉穎梁沧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝇裤,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡廷支,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了栓辜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恋拍。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖藕甩,靈堂內(nèi)的尸體忽然破棺而出施敢,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布僵娃,位于F島的核電站概作,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏默怨。R本人自食惡果不足惜讯榕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匙睹。 院中可真熱鬧愚屁,春花似錦、人聲如沸痕檬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谆棺。三九已至栽燕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間改淑,已是汗流浹背碍岔。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朵夏,地道東北人蔼啦。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像仰猖,于是被迫代替她去往敵國和親捏肢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容