Android-Java和JavaScript相互調(diào)用

當前的Android開發(fā)中,會使用大量的h5(html5+css3+js),甚至出現(xiàn)了混合開發(fā)模式(Hybrid)否淤,使用Hybrid開發(fā),h5頁面開發(fā)效率高和移植便利性為主。
但在一些地方使用h5開發(fā)的確會不太容易實現(xiàn)先紫,這個時候就需要調(diào)用Java原生方法來完成,就會遇到JavasSript和Java相互調(diào)用筹煮,用Java原生方法實現(xiàn)那些Javascript代碼不容易實現(xiàn)的功能遮精,比如,異步線程败潦,調(diào)用數(shù)據(jù)庫等..... 然后再暴露給JavaScript調(diào)用本冲。

JavascriptInterface

Android 4.2之前使用addjavascriptinterface可以把原生的Java方法,給JavaScript調(diào)用,但是這種方案卻存在安全風險,在頁面中執(zhí)行一些不可信的Javascript代碼即有可能控制用戶的手機,詳情見:WebView中接口隱患與手機掛馬利用
Android 4.2之后提供了@JavascriptInterface對象注解的方式建立Javascript對象和android原生對象的綁定,提供給JavaScript調(diào)用的方法必須帶有@JavascriptInterface劫扒。
當前4.0及4.0之前的系統(tǒng)市場占有量已經(jīng)很低了檬洞,因此可以考慮使用minSdkVersion為17,只支持4.2版本以上的手機沟饥,低版本的系統(tǒng)不再支持了添怔。
下面就看下Java和Javascript是如何通信的。

加載本地html

為了方便使用贤旷,下面使用的示例广料,不會使用server,所以就需要在webview中使用本地的html文件,為了方便把html文件都放在assets文件夾中幼驶,使用本地加載的方式艾杏,這樣就不需要服務器的支持了。
先定義一個html文件:

<!DOCTYPE html>
<html>
    <body>
        <h1>this is html</h1>
    </body>
</html>

使用file:///android_asset/index.html加載到webview中:

    private void initView() {
        webView = (WebView) findViewById(R.id.webView);
        webView.loadUrl("file:///android_asset/index.html");
    }

下面就可以在index.html中試用Java和JavaScript的調(diào)用了县遣。

Javascript調(diào)用Java方法

以Android的Toast的為例糜颠,下面看下如何從Javascript代碼中調(diào)用系統(tǒng)的Toast
先定義一個AndroidToast的Java類,它有一個show的方法用來顯示Toast:

public class AndroidToast {
        @JavascriptInterface
        public void show(String str) {
            Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
        }
    }

再對WebView進行設置萧求,開啟JavaScipt其兴,注冊JavascriptInterface的方法:

private void initView() {
        webView = (WebView) findViewById(R.id.webView);

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDefaultTextEncodingName("UTF-8");
        webView.addJavascriptInterface(new AndroidToast(), "AndroidToast");
        webView.loadUrl("file:///android_asset/index.html");
 }

addJavascriptInterface的作用是把AndroidToast類映射為Javascript中的AndroidToast。這樣就可以在JavaScript中調(diào)用Java中的方法了夸政。
在Javascript中調(diào)用Java代碼:

function toastClick(){
        window.AndroidToast.show('from js');
}

通過window屬性可以找到映射的對象AndroidToast,直接調(diào)用它的show方法即可元旬。
注意這里傳輸?shù)臄?shù)據(jù)只能是基本數(shù)據(jù)類型和string,可以傳輸string就意味著可以使用json傳輸結構化數(shù)據(jù)。
這里調(diào)用的方法并沒有返回值,如果需要在JavaScript中需要得到返回值怎么辦呢匀归?

JavaScript調(diào)用Java有返回值

如果想從Javascript調(diào)的方法里面獲取到返回值坑资,只需要定義一個帶返回值的@JavascriptInterface方法即可:


    public class AndroidMessage {
        @JavascriptInterface
        public String getMsg() {
            return "form java";
        }
    }

添加Javascript的映射:

webView.addJavascriptInterface(new AndroidMessage(), "AndroidMessage");

在JavaScript直接調(diào)用:

function showAlert(){
        var str=window.AndroidMessage.getMsg();
        console.log(str);
 }

這樣就完成了有返回值的方法調(diào)用。還有一種場景是穆端,在Java中主動觸發(fā)JavaScript方法袱贮,就需要在Java中調(diào)用JavaScript方法了。

Java調(diào)用JavaScript方法

Java在調(diào)用JavaScript方法的時候体啰,需要使用WebView.loadUrl()方法攒巍,它可以直接在頁面里執(zhí)行JavaScript方法。
首先定義一個JavaScript方法給Java調(diào)用:

function callFromJava(str){
        console.log(str);
    }

在Java中直接調(diào)用該方法:

public void  javaCallJS(){
        webView.loadUrl("javascript:callFromJava('call from java')");
    }

可以在loadUrl中給Javascript方法直接傳參荒勇,如果JavaScript方法有返回值柒莉,使用WebView.loadUrl()是無法獲取到返回值的,需要JavaScript返回值給Java的話沽翔,可以定義一個Java方法提供給JavaScript調(diào)用兢孝,然后Java調(diào)用JavaScript之后,JavaScript觸發(fā)該方法把返回值再傳遞給Java仅偎。
注意WebView.loadUrl()必須在Ui線程中運行跨蟹,不然會會報錯。

項目地址:https://github.com/jjz/android/tree/master/JSBriage

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末橘沥,一起剝皮案震驚了整個濱河市喷市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌威恼,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寝并,死亡現(xiàn)場離奇詭異箫措,居然都是意外死亡,警方通過查閱死者的電腦和手機衬潦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門斤蔓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人镀岛,你說我怎么就攤上這事弦牡。” “怎么了漂羊?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵驾锰,是天一觀的道長。 經(jīng)常有香客問我走越,道長椭豫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮赏酥,結果婚禮上喳整,老公的妹妹穿的比我還像新娘。我一直安慰自己裸扶,他們只是感情好框都,可當我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著呵晨,像睡著了一般魏保。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上何荚,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天囱淋,我揣著相機與錄音,去河邊找鬼餐塘。 笑死妥衣,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的戒傻。 我是一名探鬼主播税手,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼需纳!你這毒婦竟也來了芦倒?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤不翩,失蹤者是張志新(化名)和其女友劉穎兵扬,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體口蝠,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡器钟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了妙蔗。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片傲霸。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖眉反,靈堂內(nèi)的尸體忽然破棺而出昙啄,到底是詐尸還是另有隱情,我是刑警寧澤寸五,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布梳凛,位于F島的核電站,受9級特大地震影響播歼,放射性物質(zhì)發(fā)生泄漏伶跷。R本人自食惡果不足惜掰读,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望叭莫。 院中可真熱鬧蹈集,春花似錦、人聲如沸雇初。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽靖诗。三九已至郭怪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刊橘,已是汗流浹背鄙才。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留促绵,地道東北人攒庵。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像败晴,于是被迫代替她去往敵國和親浓冒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,969評論 2 355

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,152評論 25 707
  • WebView·開車指南 2016-08-31BugDev 北京市東城區(qū)首席Bug布道師開山之作尖坤,一整月交通事故血...
    53c021c38a1d閱讀 829評論 0 1
  • 這篇博客主要來介紹 WebView 的相關使用方法慢味,常見的幾個漏洞场梆,開發(fā)中可能遇到的坑和最后解決相應漏洞的源碼,以...
    Shawn_Dut閱讀 7,229評論 3 55
  • 前言 總結 Android WebView 常用的相關知識點纯路,令包含以下干貨內(nèi)容分析:Js注入漏洞辙谜、WebView...
    無名小子的雜貨鋪閱讀 69,812評論 17 169
  • 在過去的二十年間,敏捷軟件開發(fā)從默默無聞到日益成為業(yè)界共識感昼。不僅在軟件開發(fā)領域,敏捷運動對固件罐脊、硬件領域定嗓、乃至于非...
    Andy王威閱讀 1,445評論 0 0