第二十章 Android 中常用的WebView

我們了解過Web,對于HTTP協(xié)議,我們不是做網(wǎng)站開發(fā),Android端只需要簡單的了解基本的原理就可以了。首先由客戶端發(fā)送請求給服務(wù)端,然后服務(wù)端返回對應(yīng)的指令,最后根據(jù)返回的指令進(jìn)行解析和處理。這就是一個簡單的網(wǎng)絡(luò)交互協(xié)議。

1. WebView的用法

在做Android開發(fā)的時候,我們可能會碰到一些特殊的需求,比如說在應(yīng)用 程序中加載一個網(wǎng)頁,或者插入一些廣告啥的,而且需求中又不允許打開系統(tǒng)的瀏覽器,怎么辦?Android已經(jīng)考慮到這種需要了,所以提供了一個WebView控件,在自己的應(yīng)用程序中嵌入一個瀏覽器。這樣就可以輕松展示各種網(wǎng)頁。

WebView的用法很簡單,和一般的控件都一樣。

  1. 新建一個activity_main.xml,然后插入一個WebView 控件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <WebView
        android:id="@+id/wb_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
  1. MainActivity 設(shè)置WebView的方法
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WebView  wb_main= (WebView) findViewById(R.id.wb_main);
        wb_main.getSettings().setJavaScriptEnabled(true);//支持JavaScriptEnable
        wb_main.setWebViewClient(new WebViewClient());
        wb_main.loadUrl("http://www.baidu.com");
    }
}

通過getSetting()可以設(shè)置瀏覽器的屬性,這里用了setJavaScriptEnabled()的來讓W(xué)ebView支持JavaScript腳本。然后調(diào)用WebView的setWebViewClient()的方法并傳入一個實(shí)例。最后是希望加載的網(wǎng)頁
3.最后一步,記得加上權(quán)限

    <uses-permission android:name="android.permission.INTERNET"/>

這樣就完成了一個簡單的加載網(wǎng)頁。

2. WebView的方法

2.1 加載url

根據(jù)加載的方式不同分為三種:

  //方式1. 加載一個網(wǎng)頁:
  webView.loadUrl("http://www.baidu.com/");   // 加載url頁面
 //方式2:加載apk包中的html頁面
  webView.loadUrl("file:///android_asset/test.html");
  //方式3:加載手機(jī)本地的html頁面
   webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html"); 

// 另外1、: 加載 HTML 頁面的一小段內(nèi)容
  WebView.loadData(String data, String mimeType, String encoding) 如:
webView_main.loadData(data, "text/html","utf-8");
// 參數(shù)說明:
// 參數(shù)1:需要截取展示的內(nèi)容
// 內(nèi)容里不能出現(xiàn) ’#’, ‘%’, ‘\’ , ‘?’ 這四個字符,若出現(xiàn)了需用 %23, %25, %27, %3f 對應(yīng)來替代,否則會出現(xiàn)異常
// 參數(shù)2:展示內(nèi)容的類型
// 參數(shù)3:字節(jié)碼

//另外2、:
webView_main.loadDataWithBaseURL(null, data, "text/html", "utf-8", null);

loadDataWithBaseURL()的作用呢?難道是結(jié)合體?因?yàn)閣ebView_main.loadData(data, "text/html","utf-8");//這個方法中雖然設(shè)置了字符,但是還是會顯示中文亂碼。所以建議使用 webView_main.loadDataWithBaseURL(null, data, "text/html", "utf-8", null);

2.2 前進(jìn)后退網(wǎng)頁
//是否可以后退
Webview.canGoBack() 
//后退網(wǎng)頁
Webview.goBack()

//是否可以前進(jìn)                     
Webview.canGoForward()
//前進(jìn)網(wǎng)頁
Webview.goForward()

//以當(dāng)前的index為起始點(diǎn)前進(jìn)或者后退到歷史記錄中指定的steps
//如果steps為負(fù)數(shù)則為后退,正數(shù)則為前進(jìn)
Webview.goBackOrForward(intsteps)

如果在請求WebView的時候,進(jìn)入二級的WebView的時候,點(diǎn)擊Back鍵,實(shí)際上是整個Activity都結(jié)束,調(diào)用了finish()方法,所以這個時候需要調(diào)用goBack()方法。

 @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KEYCODE_BACK) && wb_main.canGoBack()) {
            wb_main.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

或者.

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
            if(wb_main.canGoBack() ){
                //獲取瀏覽記錄
                WebBackForwardList backForwardList= wb_main.copyBackForwardList();
                //這里的判斷是為了讓頁面在有上一個頁面的情況下,跳轉(zhuǎn)到上一個html頁面,而不是退出當(dāng)前activity
                 if(backForwardList.getCurrentIndex()>0){
                     String  historyUrl =  backForwardList.getItemAtIndex(backForwardList.getCurrentIndex()-1).getUrl();
                     if(historyUrl !=url ){
                         wb_main.goBack();
                         return true;
                     }
                 }

            } else{
                return  true;
            }
        }
        return true;
    }

2.3 緩存
//清除網(wǎng)頁訪問留下的緩存
//由于內(nèi)核緩存是全局的因此這個方法不僅僅針對webview而是針對整個應(yīng)用程序.
Webview.clearCache(true);

//清除當(dāng)前webview訪問的歷史記錄
//只會webview訪問歷史記錄里的所有記錄除了當(dāng)前訪問記錄
Webview.clearHistory();

//這個api僅僅清除自動完成填充的表單數(shù)據(jù),并不會清除WebView存儲到本地的數(shù)據(jù)
Webview.clearFormData();

1.2 WebView的常用類

1.2.1 WebSetting類

WebView加載網(wǎng)頁內(nèi)容,但是對于HTML文本的Javascript代碼卻無法加載運(yùn)行。為了解決這個問題要借助WebSettings類。WebSettings類除了可以設(shè)置是否支持Javascript外,還具有set系列方法來設(shè)置WebView的屬性和狀態(tài)。WebSettings對象通過WebView對象的getSettings()方法來獲取

方法 描述
setJavaScriptEnabled(boolean flag) 設(shè)置是否支持Javascript
setBlockNetworkImage(boolean flag) 設(shè)置是否阻止網(wǎng)絡(luò)圖片加載
setBuiltInZoomControls(boolean enabled) 將HTML文本內(nèi)容加載到WebView中
setCacheMode(int mode) 設(shè)置緩存模式
setDefaultFontSize(int size) 設(shè)置默認(rèn)字體大小
setFixedFontFamily(String font) 設(shè)置固定使用的字體
setDefaultTextEncodingName(String encoding) 設(shè)置解碼時默認(rèn)的字符集
setSupportZoom(boolean support) 設(shè)置是否支持變焦
setAllowFileAccess(boolean allow) 設(shè)置是否允許訪問WebView中文件。就是file:///android_asset和file:///android_res路徑下的資產(chǎn)和資源文件。默認(rèn)允許訪問。

注意:5.1以上默認(rèn)禁止了https和http混用 這是開啟
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}

2.4 WebViewClient類

WebView解決了支持Javascript的問題。但是新的問題又出來了。當(dāng)點(diǎn)擊WebView中的超鏈接后,原本希望目標(biāo)網(wǎng)頁在當(dāng)前WebView中顯示,但是卻打開了系統(tǒng)瀏覽器來加載目標(biāo)網(wǎng)頁。為了解決這個問題,要借助WebViewClient類。WebViewClient類專門用來輔助WebView處理各種通知、請求等事件。通過WebView對象調(diào)用setWebViewClient()方法來指定一個WebViewClient對象,重寫WebViewClient對象中的shouldOverrideUrlLoading()方法,使得當(dāng)有新連接時,使用當(dāng)前WebView來顯示網(wǎng)頁。WebViewClient除此之外,還有其他的方法

方法 描述
shouldOverrideUrlLoading() 新的鏈接在當(dāng)前WebView中打開
onPageStarted() 網(wǎng)頁開始加載
onPageFinished() 網(wǎng)頁加載完畢
doUpdateVisitedHistory() 更新訪問歷史記錄的數(shù)據(jù)庫
onLoadResource() 加載指定Url地址提供的資源
onFormResubmission() 應(yīng)用程序重新請求網(wǎng)頁數(shù)據(jù)
onScaleChanged() WebView發(fā)生改變
2.5 WebChromeClient類

對于網(wǎng)頁中一般的Javascript都可以被WebView加載執(zhí)行了。但是某些特殊的Javascript語句依然無法執(zhí)行。例如Javascript語句中的Alert、Confirm、Prompt等對話框。為了解決這個問題,要借助WebChromeClient類。WebChromeClient類專門用來輔助WebView處理Javascript的對話框、網(wǎng)站圖標(biāo)、網(wǎng)站Title、加載進(jìn)度等。

方法 描述
onJsAlert() 處理Javascript中Alert對話框
onJsConfirm() 處理Javascript中Confirm對話框
onJsPrompt() 處理Javascript中Prompt對話框
onProgressChanged() 加載進(jìn)度條改變
onCloseWindow() 關(guān)閉WebView
onCreateWindow() 創(chuàng)建WebView
onReceivedIcon() Icon圖標(biāo)改變
onReceivedTitle() 網(wǎng)頁Title改變
onRequestFocus() WebView顯示焦點(diǎn)

3. Android 和Js的交互

在實(shí)際開發(fā)過程中,Android與Js的交互都是通過WebView來完成的。WebView是二者之間的橋梁。

  • Android 調(diào)用Js的代碼
  • Js調(diào)用Android的代碼
Android與Js的交互

3.1 Android 調(diào)用JS的代碼

我們是做安卓開發(fā)的,所以在實(shí)際的開發(fā)過程中,有h5的人會寫好對應(yīng)的方法,然后我們只需要根據(jù)它提供給我們的方法,調(diào)起js的代碼就可以了。這里寫一個例子來說明一下。

調(diào)用JS前
調(diào)用JS后
  1. 首先在一個布局文件中有這樣兩個控件。activity_main2.xml.一個Button,一個WebView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:text="@string/btn_click"
    />
    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

  1. 接下來在assert文件下創(chuàng)建一個html文件。(創(chuàng)建asserts文件,main->New->Folder->Asserts Folder),(創(chuàng)建html文件,可以自己創(chuàng)建一個File文件,然后后綴加上 login.html)
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Carson_Ho</title>
    <script>
         function callJS(){
             alert("Android調(diào)用了JS的callJS方法");
        }
</script>

</head>

</html>
  1. 接下來就是對布局的一些處理,上圖的邏輯很簡單,我們在點(diǎn)擊按鈕的時候出發(fā)彈窗,然后根據(jù)彈窗吊起Js。
public class Main2Activity extends AppCompatActivity {
    WebView mWebView;
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        mWebView =(WebView) findViewById(R.id.webView);
        WebSettings webSettings = mWebView.getSettings();
        // 設(shè)置與Js交互的權(quán)限
        webSettings.setJavaScriptEnabled(true);
        // 設(shè)置允許JS彈窗
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        // 先載入JS代碼
        // 格式規(guī)定為:file:///android_asset/文件名.html
        mWebView.loadUrl("file:///android_asset/login.html");
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 通過Handler發(fā)送消息
                mWebView.post(new Runnable() {
                    @Override
                    public void run() {
                        // 注意調(diào)用的JS方法名要對應(yīng)上
                        // 調(diào)用javascript的callJS()方法
                        mWebView.loadUrl("javascript:callJS()");
                    }
                });

            }
        });

        // 由于設(shè)置了彈窗檢驗(yàn)調(diào)用結(jié)果,所以需要支持js對話框
        // webview只是載體,內(nèi)容的渲染需要使用webviewChromClient類去實(shí)現(xiàn)
        // 通過設(shè)置WebChromeClient對象處理JavaScript的對話框
        //設(shè)置響應(yīng)js 的Alert()函數(shù)
        mWebView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                AlertDialog.Builder b = new AlertDialog.Builder(Main2Activity.this);
                b.setTitle("Alert");
                b.setMessage(message);
                b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        result.confirm();
                    }
                });
                b.setCancelable(false);
                b.create().show();
                return true;
            }

        });


    }
}

【注意】永遠(yuǎn)不要阻塞UI線程,這是開發(fā)Android程序的一個真理。雖然是真理,我們卻往往不自覺的犯一些錯誤違背它,一個開發(fā)中常犯的錯誤就是:在UI線程中去等待JavaScript 的回調(diào)。Android 4.4中,提供了新的Api來做這件事情。evaluateJavascript() 就是專門來異步執(zhí)行JavaScript代碼的。專門用于異步調(diào)用JavaScript方法,并且能夠得到一個回調(diào)結(jié)果。

調(diào)用方式 優(yōu)點(diǎn) 缺點(diǎn) 使用場景
使用loadUrl() 方便簡潔 效率低;無返回值 無需返回值,對性能要求低
使用evaluateJavascript() 效率高 向下兼容差(4.4以上) Android 4.4以上
mWebView.evaluateJavascript(script, new ValueCallback<String>() {
     @Override
     public void onReceiveValue(String value) {
          //返回Js的結(jié)果
     }
});

修改代碼,既兼容4.4以上,有包括4.4以下

  button.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void onClick(View v) {
                if(Build.VERSION.SDK_INT<19){
                  mWebView.post(new Runnable() {
                      @Override
                      public void run() {
                          mWebView.loadUrl("javascript:callJS()");
                      }
                  });
                }else{
                      //已經(jīng)是異步了,無需再開下線程了
                    mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
                        @Override
                        public void onReceiveValue(String s) {
                            Log.e(TAG, "onReceiveValue: "+s );
                        }
                    });
                }
            }
        });

3.2 JS調(diào)用安卓的代碼

在安卓實(shí)際開發(fā)過程中,JS的一些代碼,也可以調(diào)用安卓的功能。方法有以下三種:

3.2.1 通過WebView的addJavascriptInterface()進(jìn)行對象映射

具體的方法:

  1. 定義一個與JS對象映射關(guān)系的Android類,然后定義一個JS需要調(diào)用的方法
public class Main3JS  extends Object {
    // 定義JS需要調(diào)用的方法
    // 被JS調(diào)用的方法必須加入@JavascriptInterface注解
    @JavascriptInterface
    public  void  ToJs(String msg){
        Log.e("tag","JS調(diào)用Android的代碼");
    }
}
  1. 編寫一個html文件,registe.html。定義一個test對象,然后調(diào)用Android 映射的對象,最后在點(diǎn)擊按鈕的時候,其實(shí)就是在調(diào)用callAndroid()這個函數(shù)。
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script>
         function callAndroid(){
             // 由于對象映射,所以調(diào)用test對象等于調(diào)用Android映射的對象
            test.ToJs("js調(diào)用了android中的ToJs方法");
        }
</script>

</head>
<body>

<button type="button" id="button1" onclick="callAndroid()" >JS點(diǎn)擊調(diào)用安卓的代碼</button>
</body>
</html>

  1. 新建一個Main3Activity文件,布局里面只有一個webView。設(shè)置加載JS的方法,然后調(diào)用addJavascriptInterface()這個方法,將第一步的Main3J類帶入,然后是第二個test對象。
public class Main3Activity extends AppCompatActivity {
    WebView mWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        mWebView = (WebView) findViewById(R.id.WebView);
        WebSettings webSettings = mWebView.getSettings();

        // 設(shè)置與Js交互的權(quán)限
        webSettings.setJavaScriptEnabled(true);

        // 通過addJavascriptInterface()將Java對象映射到JS對象
        //參數(shù)1:Javascript對象名
        //參數(shù)2:Java對象名
        mWebView.addJavascriptInterface(new Main3JS(this), "test");//AndroidtoJS類對象映射到j(luò)s的test對象

        // 加載JS代碼
        // 格式規(guī)定為:file:///android_asset/文件名.html
        mWebView.loadUrl("file:///android_asset/registe.html");
    }
}

最后結(jié)果如上圖所示。這種方法使用簡單,僅將Android對象和JS對象映射即可。但是存在數(shù)據(jù)泄露的風(fēng)險。

3.2.2 通過 WebViewClient 的方法shouldOverrideUrlLoading ()回調(diào)攔截 url

回調(diào)攔截url的原理很簡單,Android 通過WebViewClient的回調(diào)方法shouldOverrideUrlLoading ()攔截 url,然后解析url,根據(jù)設(shè)定的url協(xié)議調(diào)用不同的方法。

  • 具體步驟
  1. 編寫一個html文件,定義一個協(xié)議。當(dāng)Js通過Android 的加載的協(xié)議后,就會回調(diào)shouldOverrideUrlLoading ()方法。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <script>
         function callAndroid(){
          //定義協(xié)議
          document.location="js://webview?location=1";
        }
</script>

</head>
<body>

<button type="button" id="button1" onclick="callAndroid()" >JS點(diǎn)擊調(diào)用安卓的代碼</button>
</body>
</html>

2.在Main4Activity 中定義webView,然后加載協(xié)議,最后調(diào)用webview的shouldOverrideUrlLoading ()方法。根據(jù)js.html的定義的協(xié)議格式:根據(jù)scheme(協(xié)議格式) & authority(協(xié)議名)判斷(前兩個參數(shù))進(jìn)行判斷。

public class Main4Activity extends AppCompatActivity {
    private WebView webView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main4);
        webView = (WebView) findViewById(R.id.webView);
        WebSettings webSettings= webView.getSettings();
        //設(shè)置加載JS權(quán)限
        webSettings.setJavaScriptEnabled(true);
        //設(shè)置允許JS彈窗
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
         //加載file文件

        webView.loadUrl("file:///android_asset/sencodJs.html");

         webView.setWebViewClient(new WebViewClient(){
             // 一般根據(jù)scheme(協(xié)議格式) & authority(協(xié)議名)判斷(前兩個參數(shù))
             // "js://webview?location=1"
             @Override
             public boolean shouldOverrideUrlLoading(WebView view, String url) {
                 Uri uri = Uri.parse(url);
                 //如果url的協(xié)議 = 預(yù)先約定的 js 協(xié)議
                  if(uri.getScheme().equals("js")){
                      // 如果 authority  = 預(yù)先約定協(xié)議里的 webview,即代表都符合約定的協(xié)議
                       if(uri.getAuthority().equals("webview")){
                            // 執(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();
                           AlertDialog.Builder mBuilder= new AlertDialog.Builder(Main4Activity.this);
                           mBuilder.setTitle("Alert");
                           mBuilder.setMessage("JS要調(diào)用Android的代碼");
                           mBuilder.setCancelable(true);
                           mBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                               @Override
                               public void onClick(DialogInterface dialogInterface, int i) {
                                   dialogInterface.dismiss();
                               }
                           });
                           mBuilder.create().show();

                       }
                        return  true;
                  }
                 return super.shouldOverrideUrlLoading(view, url);
             }
         });
    }
}

通過解析協(xié)議里面的值來進(jìn)行調(diào)用android里面的代碼。這樣可以避免數(shù)據(jù)邪路的風(fēng)險,但是返回數(shù)據(jù)麻煩。當(dāng)用戶點(diǎn)擊webview中的網(wǎng)頁鏈接的時候,安卓系統(tǒng)默認(rèn)會啟動一個新的應(yīng)用專門成立url的跳轉(zhuǎn)。如果希望點(diǎn)擊鏈接繼續(xù)在當(dāng)前webview中響應(yīng),而不是新開Android的系統(tǒng)browser中響應(yīng)該鏈接,必須覆蓋 WebView的WebViewClient對象. 并重寫shouldOverrideUrlLoading方法。

3.2.3 通過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回調(diào)攔截JS對話框alert()、confirm()、prompt() 消息
方法 作用 返回值 備注
alert() 彈出警告框 在文本中加入\n可換行
confirm() 彈出確認(rèn)框 兩個 返回布爾值(true,false)
prompt() 彈出輸入框 任意設(shè)置返回值 確認(rèn):返回輸入框中的值;取消返回null
  • 具體方法
    1.首先在three.html中設(shè)置點(diǎn)擊按鈕和調(diào)用的js方法
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Carson_Ho</title>

    <script>

    function clickprompt(){
    // 調(diào)用prompt()
    var result=prompt("js://webview?arg1=111&arg2=222");
    alert("demo " + result);
}

      </script>
</head>

<!-- 點(diǎn)擊按鈕則調(diào)用clickprompt()  -->
<body>
<button type="button" id="button1" onclick="clickprompt()">點(diǎn)擊調(diào)用Android代碼</button>
</body>
</html>

2.然后在Main5Activity方法中,自頂一個WebView,然后調(diào)用WebView的WebChromeClient(),重寫里面的回調(diào)攔截方法


public class Main5Activity extends AppCompatActivity {

    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main5);
        webView = (WebView) findViewById(R.id.webView);
        WebSettings  webSettings=webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webView.loadUrl("file:///android_asset/three.html");
        webView.setWebChromeClient(new WebChromeClient(){

            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                Uri uri = Uri.parse(message);
                if (uri.getScheme().equals("js")) {
                    if (uri.getAuthority().equals("webview")) {
                        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);
            }

            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                return super.onJsAlert(view, url, message, result);
            }

            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
                return super.onJsConfirm(view, url, message, result);

            }
        });
    }
}

調(diào)用前
調(diào)用后

github地址:https://github.com/wangxin3119/MyWebViewDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,570評論 2 379

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