webView和js交互的方式

交互方式總結(jié)

  • Android調(diào)用JS方法兩種方式
  1. 通過WebView的loadUrl()方式;
  2. 通過WebView的evaluateJavascript()方式;
  • JS調(diào)用Android的三種方式
  1. 通過WebView的addJavascriptInterface()進行對象的映射
  2. 通過 WebViewClient 的shouldOverrideUrlLoading ()方法回調(diào)攔截 url
  3. 通過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回調(diào)攔截JS對話框alert()孕讳、confirm()丙笋、prompt() 消息

Android調(diào)用JS方法的兩種方法具體分析

通過WebView的loadUrl()方式

1.方便演示用本地的html文件來做演示

  • 需要加載的本地js.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Carson_Ho</title>


    <script>
// Android需要調(diào)用的方法
   function callJS(){
      alert("Android調(diào)用了JS的callJS方法");
   }
   function callAndroid(){
        test.hello("js調(diào)用了Android中的hello方法");
   }
   function callAndroidofOverrideloadurl(){
        document.location = "js://webview?arg1=111&arg2=222";
   }
   function returnResult(result){
        alert("android return result:"+result);
   }
   function clickprompt(){
        var result=prompt("js://demo?arg1=111&arg2=222");
        alert("demo:" + result);
   }
</script>

</head>
<body>
    <button type="button" id="button1" onclick="callAndroid()">點擊按鈕調(diào)用callAndroid函數(shù)</button>
    <button type="button" id="button2" onclick="callAndroidofOverrideloadurl()">點擊按鈕調(diào)用callAndroid函數(shù)通過overrideloadurl</button>
    <button type="button" id="button3" onclick="clickprompt()">通過prompt調(diào)用Android代碼</button>
</body>
</html>
  • Android端的代碼如下所示
package com.example.webview;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Set;

public class MainActivity extends AppCompatActivity {

    WebView mWebView;
    Button callJSButton;
    Button returnResultJs;
    int version = Build.VERSION.SDK_INT;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mWebView = (WebView) findViewById(R.id.webview);
        returnResultJs = (Button) findViewById(R.id.return_result);

        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setJavaScriptEnabled(true);

        mWebView.addJavascriptInterface(new AndroidtoJs(MainActivity.this),"test");
        mWebView.loadUrl("file:///android_asset/js.html");

        mWebView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Uri uri = Uri.parse(url);
                if(uri.getScheme().equals("js")){
                    if(uri.getAuthority().equals("webview")){
                        HashMap<String, String> params = new HashMap<>();
                        Set<String> collection = uri.getQueryParameterNames();
                        String arg1 = collection.toString();
                    }
                }
                return super.shouldOverrideUrlLoading(view, url);
            }
        });
        returnResultJs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int result = 100;
                mWebView.loadUrl("javascript:returnResult(" +"\"" + result + "\"" + ")");
//                int version = Build.VERSION.SDK_INT;
//                if(version <19){
//                    mWebView.loadUrl("javascript:returnResult(" + "faffdsfsfsafdasdfds" + ")");
//                }else{
//                    mWebView.evaluateJavascript("javascript:returnResult(" + "faffdsfsfsafdasdfds" + ")", new ValueCallback<String>() {
//                        @Override
//                        public void onReceiveValue(String value) {
//
//                        }
//                    });
//                }
            }
        });

        callJSButton = (Button) findViewById(R.id.call_js);
        callJSButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mWebView.post(new Runnable() {
                    @Override
                    public void run() {
                        int version = Build.VERSION.SDK_INT;
                        if(version <19){
                            mWebView.loadUrl("javascript:callJS()");
                        }else{
                            mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
                                @Override
                                public void onReceiveValue(String value) {

                                }
                            });
                        }
                    }
                });
            }
        });

        mWebView.setWebChromeClient(new WebChromeClient(){
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setTitle("MY WEBVIEW ALERT");
                builder.setMessage(message);
                builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        result.confirm();
                    }
                });
                builder.setCancelable(false);
                builder.create().show();
                return true;
            }

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

                Uri uri = Uri.parse(message);
                if ( uri.getScheme().equals("js")) {

                    // 如果 authority  = 預(yù)先約定協(xié)議里的 webview缎罢,即代表都符合約定的協(xié)議
                    // 所以攔截url,下面JS開始調(diào)用Android需要的方法
                    if (uri.getAuthority().equals("demo")) {

                        //
                        // 執(zhí)行JS所需要調(diào)用的邏輯
                        System.out.println("js調(diào)用了Android的方法");
                        // 可以在協(xié)議上帶有參數(shù)并傳遞到Android上
                        HashMap<String, String> params = new HashMap<>();
                        Set<String> collection = uri.getQueryParameterNames();

                        //參數(shù)result:代表消息框的返回值(輸入值)
                        result.confirm("js調(diào)用了Android的方法成功啦");
                    }
                    return true;
                }
                return super.onJsPrompt(view, url, message, defaultValue, result);
            }
        });
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌脓匿,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宦赠,死亡現(xiàn)場離奇詭異陪毡,居然都是意外死亡,警方通過查閱死者的電腦和手機勾扭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門毡琉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人妙色,你說我怎么就攤上這事桅滋。” “怎么了身辨?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵丐谋,是天一觀的道長芍碧。 經(jīng)常有香客問我,道長号俐,這世上最難降的妖魔是什么师枣? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮萧落,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘洗贰。我一直安慰自己找岖,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布敛滋。 她就那樣靜靜地躺著许布,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绎晃。 梳的紋絲不亂的頭發(fā)上蜜唾,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機與錄音庶艾,去河邊找鬼袁余。 笑死,一個胖子當(dāng)著我的面吹牛咱揍,可吹牛的內(nèi)容都是我干的颖榜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼煤裙,長吁一口氣:“原來是場噩夢啊……” “哼掩完!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起硼砰,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤且蓬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后题翰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恶阴,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年遍愿,在試婚紗的時候發(fā)現(xiàn)自己被綠了存淫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡沼填,死狀恐怖桅咆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坞笙,我是刑警寧澤岩饼,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布荚虚,位于F島的核電站,受9級特大地震影響籍茧,放射性物質(zhì)發(fā)生泄漏版述。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一寞冯、第九天 我趴在偏房一處隱蔽的房頂上張望渴析。 院中可真熱鬧,春花似錦吮龄、人聲如沸俭茧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽母债。三九已至,卻和暖如春尝抖,著一層夾襖步出監(jiān)牢的瞬間毡们,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工昧辽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衙熔,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓奴迅,卻偏偏與公主長得像青责,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子取具,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

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