Android中WebView的使用指南:

參考文獻(xiàn):
Carson_Ho的Android:這是一份全面 & 詳細(xì)的Webview使用攻略

本文知識(shí)點(diǎn):

  • WebView的介紹
  • WebView的基本使用
  • WebView的一些開(kāi)發(fā)中常用的API
  • WebView中一些常見(jiàn)的案例分析及實(shí)現(xiàn)
這里盜用Carson的一張圖片,如果覺(jué)得不妥,及時(shí)告知馬上刪除

1.WebView的介紹

相信做Android的基本上都用過(guò)WebView,不論是加載網(wǎng)頁(yè)還是處理本地內(nèi)容,基本上都或多或少的使用過(guò)WebView。那么WebView能為我們帶來(lái)什么呢?其實(shí)就相當(dāng)于一個(gè)內(nèi)置的瀏覽器,我們可以使用它完成一下操作:

1.WebView可以加載網(wǎng)頁(yè)
2.WebView可以加載html片段
3.WebView可以加載本地html
4.WebView與原生App進(jìn)行交互
以上種種都是WebView能幫我們完成的內(nèi)容,所以現(xiàn)在有很多App就采用混合開(kāi)發(fā)。這樣使得我們使用WebView的場(chǎng)景越來(lái)越多,所以這里總結(jié)一下關(guān)于WebView的一些內(nèi)容。

2.WebView的基本使用

其實(shí)如果你只用WebView加載一個(gè)網(wǎng)頁(yè)的話,還是很好上手的?;旧暇腿剑?/p>

  • 在AndroidManifest注冊(cè)網(wǎng)絡(luò)權(quán)限:這個(gè)是必須的,切記切記?。。?/li>
 <uses-permission android:name="android.permission.INTERNET" />
  • 加載相應(yīng)的網(wǎng)頁(yè)資源
webView.loadUrl(url);

但是這里雖然加載的是一個(gè)url,但是你會(huì)發(fā)現(xiàn)他會(huì)直接蹦到系統(tǒng)自帶的瀏覽器中去。作為強(qiáng)大的開(kāi)發(fā)人員,怎么處理呢?當(dāng)然是有辦法的了。。。

  • 設(shè)置相應(yīng)的本APP內(nèi)打開(kāi)的方法;
        webView.setWebViewClient(new WebViewClient() {
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                view.loadUrl(String.valueOf(request.getUrl()));
                return true;
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

上面的代碼有幾點(diǎn)需要說(shuō)明一下:

  • shouldOverrideUrlLoading(WebView view, WebResourceRequest request) 這個(gè)方法是在5.0以上的版本上使用的,而shouldOverrideUrlLoading(WebView view, String url)這個(gè)方法是在5.0以下使用的,有了這兩個(gè)方法,就能在自己的APP中打開(kāi)相應(yīng)的網(wǎng)頁(yè)鏈接了。。。

上面就是WebView的簡(jiǎn)單實(shí)用,基本上就是展示一個(gè)網(wǎng)頁(yè),沒(méi)有相應(yīng)的交互問(wèn)題。

3.WebView一些開(kāi)中常用的API

加載類:

  • loadUrl(string url) 加載url地址的方法,參數(shù)就是一個(gè)Url地址;這里有一個(gè)點(diǎn)需要注意一下,這個(gè)方法加載的地址可以是
    • 網(wǎng)址 如 -> http://www.baidu.com
    • 手機(jī)本地html地址 如-> file:///android_asset/test.html
    • app包中assect目錄下的html文件 如 -> content://com.android.htmlfileprovider/sdcard/test.html
  • loadData(String data, String mimeType, String encoding) 加載html片段
    • 參數(shù)1:html片段
    • 參數(shù)2:類型
    • 參數(shù)3:編碼格式

狀態(tài)類

  • onResume() 當(dāng)webView為活躍狀態(tài)的時(shí)候回調(diào)此方法(獲取焦點(diǎn))
  • onPause() 切換到后臺(tái)的時(shí)候回調(diào)此方法(失去焦點(diǎn))

其實(shí)上面這兩個(gè)方法是和生命周期匹配的兩個(gè)方法

  • pauseTimers() 全局范圍切換到后臺(tái)降低cpu功耗時(shí)回調(diào)的方法
  • resumeTimers() 恢復(fù)正常狀態(tài)的時(shí)候回調(diào)的方法

上面這兩個(gè)方法,是為了提高自己APP的性能的方法,主要是在生命周期的方法中調(diào)用的,也就是說(shuō)在Activity的onResume()和onPause()中調(diào)用的(個(gè)人感覺(jué)啊。。。)

  • destroy() 銷毀WebView的方法(主要是在音視頻的時(shí)候,在這里釋放相應(yīng)的WebView,這里也是對(duì)應(yīng)相應(yīng)生命周期的方法的,但是這里注意一點(diǎn),在銷毀前必須先移除WebView,因?yàn)閃ebView會(huì)持有相應(yīng)Activity的上下文引用所以這里要使用其父布局調(diào)用相應(yīng)的removeView(View view)的方法進(jìn)行移除)

操作網(wǎng)頁(yè)類

  • canGoBack() 是否可以后退
  • goBack() 回退
  • canGoForward() 是否可以前進(jìn)
  • goForward() 前進(jìn)網(wǎng)頁(yè)
  • **goBackOrForward(intsteps) ** 前進(jìn)或者后退指定的位置,正數(shù)為前進(jìn)/負(fù)數(shù)為后退

這里面涉及到的主要內(nèi)容就是操作網(wǎng)頁(yè)的前進(jìn)和后退,主要應(yīng)用場(chǎng)景是什么呢?試想一下,有的WebView是嵌到APP中的,一般這樣的網(wǎng)頁(yè)都是沒(méi)有標(biāo)題的,標(biāo)題的交互留給APP處理返回的問(wèn)題,就會(huì)用到上面相應(yīng)的API了,基本上都是處理相應(yīng)的返回問(wèn)題

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

上面兩段代碼是一樣的,但是這里有一個(gè)很重要的問(wèn)題需要注意一下,很重要啊:
有些網(wǎng)頁(yè)存在重定向的時(shí)候,那么canGoBack()返回的會(huì)一直是true,我這里使用的是百度的鏈接,因?yàn)榘俣戎囟ㄏ蛄?,所以一直返回的是true,如果這里要是自己公司開(kāi)發(fā)的Url的話,應(yīng)該不會(huì)出現(xiàn)這種情況!這里提供一種解決辦法

    @Override
    public void goBack() {
        WebBackForwardList mWebBackForwardList = copyBackForwardList();
        // 判斷當(dāng)前歷史列表是否最頂端,其實(shí)canGoBack已經(jīng)判斷過(guò)
        if (mWebBackForwardList.getCurrentIndex() > 0) {
            // 獲取歷史列表
            String historyUrl = mWebBackForwardList.getItemAtIndex(
                    mWebBackForwardList.getCurrentIndex() - 1).getUrl();
            if (historyUrl.equals("https://www.baidu.com/")) {
                //回到首頁(yè)了
                Activity activity = (Activity) mContext;
                activity.finish();
            }
        }
        super.goBack();
    }

上面的代碼就是拷貝出所有前進(jìn)的頁(yè)面,然后判斷因?yàn)檫@里重定向了,所以你getUrl()獲取的網(wǎng)址永遠(yuǎn)是重定向那個(gè),所以這里我就想直接把網(wǎng)址寫(xiě)死的話就能處理了,但是我覺(jué)得我的解決辦法比較笨,還請(qǐng)大神們指教?。?!

緩存類

  • clearCache(true) 清除WebView產(chǎn)生的所有緩存
  • clearHistory() 清除當(dāng)前WebView訪問(wèn)的歷史數(shù)據(jù)
  • clearFormData() 清除表單數(shù)據(jù)

WebSettings類

這個(gè)類是對(duì)WebView進(jìn)行管理和設(shè)置的

  • getSettings() 獲取WebSettings的
  • setJavaScriptEnabled(boolean flag); 是否可以和js進(jìn)行交互
  • setPluginState(PluginState state) 是否支持插件,這里面?zhèn)鬟f的是一個(gè)枚舉對(duì)象
    • WebSettings.PluginState.OFF 不支持
    • WebSettings.PluginState.ON 支持
  • setUseWideViewPort(boolean use) 是否將圖片調(diào)整到WebView的大小
  • setLoadWithOverviewMode(boolean overview) 是否將WebView調(diào)整到屏幕大小

上面兩個(gè)API一起使用!切記,因?yàn)橹挥羞@樣才能讓界面看上去不那么丑!

  • setSupportZoom(boolean support)支持縮放,默認(rèn)為true。是下面這個(gè)API的前提。

  • setBuiltInZoomControls(boolean enabled) 設(shè)置內(nèi)置的縮放控件。若為false,則該WebView不可縮放

  • setDisplayZoomControls(boolean enabled) 隱藏原生的縮放控件,這里可以自己在頁(yè)面中實(shí)現(xiàn)。

  • setCacheMode(@CacheMode int mode) 設(shè)置緩存的模式

    • WebSettings.LOAD_DEFAULT 默認(rèn)的模式 根據(jù)cache-control決定是否從網(wǎng)絡(luò)上取數(shù)據(jù)。
    • WebSettings.LOAD_CACHE_ELSE_NETWORK 只要本地有,無(wú)論是否過(guò)期,或者no-cache,都使用緩存中的數(shù)據(jù)
    • WebSettings.LOAD_NO_CACHE 不使用緩存
    • WebSettings.LOAD_CACHE_ONLY 不使用網(wǎng)絡(luò),只加載緩存
  • setAllowFileAccess(boolean allow) 設(shè)置可以訪問(wèn)app中assect中的文件

  • setJavaScriptCanOpenWindowsAutomatically(boolean flag) 支持通過(guò)JS打開(kāi)新窗口

  • setLoadsImagesAutomatically(boolean flag) 支持自動(dòng)加載圖片

  • setDefaultTextEncodingName(String encoding) 設(shè)置編碼格式

  • setRenderPriority(RenderPriority priority) 設(shè)置渲染的優(yōu)先級(jí),這里傳入的是一個(gè)枚舉

    • NORMAL 正常
    • HIGH 高
    • LOW 低

WebViewClient類

處理各種通知和請(qǐng)求事件的控制類

  • shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
  • shouldOverrideUrlLoading(WebView view, String url)

下面這個(gè)方法已經(jīng)過(guò)時(shí)了,最新的是上面的那個(gè)方法,對(duì)于相應(yīng)的url可以通過(guò)WebResourceRequest進(jìn)行獲取。重寫(xiě)這兩個(gè)方法自己處理的話,可以不使用相應(yīng)的瀏覽器進(jìn)行打開(kāi),在本APP中打開(kāi),這也是一開(kāi)始的時(shí)候?yàn)槭裁匆貙?xiě)這個(gè)方法。

  • onPageStarted(WebView view, String url, Bitmap favicon) 加載WebView開(kāi)始的時(shí)候回調(diào)的方法,一般都在這里添加相應(yīng)的Loadding,與用戶交互,告訴用戶頁(yè)面還沒(méi)有加載完成;
  • onPageFinished(WebView view, String url) WebView加載完成的時(shí)候回調(diào)的方法和上面那個(gè)方法是相呼應(yīng)的,可以在這里關(guān)閉相應(yīng)的對(duì)話框!

這里有一個(gè)問(wèn)題注意一下,還是重定向的問(wèn)題。如果這個(gè)網(wǎng)頁(yè)重定向了,那么上面這兩個(gè)方法會(huì)被多次調(diào)用!

  • onLoadResource(WebView view, String url) 這個(gè)方法會(huì)在每次加載資源的時(shí)候回調(diào),如果圖片很多的話,會(huì)被調(diào)用多次。后面這個(gè)url代表的是相應(yīng)加載的地址。

  • onReceivedError(WebView view, int errorCode,String description, String failingUrl)

  • onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)

上面這個(gè)方法已經(jīng)過(guò)時(shí)了,可以根據(jù)相應(yīng)的code進(jìn)行判斷。后面這個(gè)方法主要是通過(guò)WebResourceError的錯(cuò)誤編碼進(jìn)行相應(yīng)的判斷,處理相應(yīng)的錯(cuò)誤!這個(gè)方法的主要作用是加載錯(cuò)誤的回調(diào)。

  • onReceivedError(WebView view, int errorCode,String description, String failingUrl)
  • onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)

這兩個(gè)方法是處理相應(yīng)的https的網(wǎng)絡(luò)請(qǐng)求的(webView默認(rèn)是不處理https請(qǐng)求的,頁(yè)面會(huì)顯示空白,使用如上面的方法進(jìn)行處理)

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                super.onReceivedSslError(view, handler, error);
                handler.proceed();
            }

            // 特別注意:5.1以上默認(rèn)禁止了https和http混用,以下方式是開(kāi)啟
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
            }

WebChromeClient類

如果你對(duì)控制類沒(méi)有那么多要求的話,使用上面的控制類就可以了,但是如果你要求比較高的話,就要用到下面這個(gè)控制類了

  • onProgressChanged(WebView view, int newProgress) 這個(gè)回調(diào)會(huì)實(shí)時(shí)的返回網(wǎng)頁(yè)加載的總進(jìn)度,最大值是100,可以根據(jù)當(dāng)前值顯示進(jìn)度。
  • onReceivedTitle(WebView view, String title) 獲取當(dāng)前加載網(wǎng)頁(yè)的標(biāo)題
  • onJsAlert(WebView view, String url, String message, JsResult result) 如果這里返回true,那么js中彈出的警告對(duì)話框就由客戶端處理;
  • onJsAlert(WebView view, String url, String message, JsResult result) 如果這里返回true,那么js中彈出的確認(rèn)對(duì)話框就由客戶端處理;
  • **onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) ** 如果這里返回true,那么js中彈出的提示對(duì)話框?qū)⒂煽蛻舳诉M(jìn)行處理。

4.WebView中一些常見(jiàn)的案例分析及實(shí)現(xiàn)

WebView顯示進(jìn)度

由很多APP中由都嵌入WebView,不知道大家仔細(xì)看過(guò)沒(méi)有,有的WebView在加載的時(shí)候頂部由一個(gè)進(jìn)度條,提示用戶加載的進(jìn)度,其實(shí)很好實(shí)現(xiàn),這里就帶大家實(shí)現(xiàn)一下:

效果圖
  • 頁(yè)面搭建
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.demo.MainActivity">

    <ProgressBar
        android:id="@+id/pb_progress"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:background="@drawable/progress_bg" />

    <WebView
        android:id="@+id/wb"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

這里就不講解ProgressBar實(shí)現(xiàn)水平進(jìn)度條了,百度一大堆!!!

  • 代碼實(shí)現(xiàn)
    private java.lang.String mUrl = "https://www.baidu.com/";
    private WebView mWb;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWb = findViewById(R.id.wb);

        progressBar = findViewById(R.id.pb_progress);
        progressBar.setMax(100);

        setWebView(mWb);
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void setWebView(WebView wb) {
        WebSettings settings = wb.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setPluginState(WebSettings.PluginState.ON);
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(true);
        settings.setSupportZoom(true);

        wb.loadUrl(mUrl);
        wb.setWebViewClient(new WebViewClient() {
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                view.loadUrl(String.valueOf(request.getUrl()));
                return true;
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

        wb.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                progressBar.setProgress(newProgress);
            }
        });
    }

主要代碼就這么多就能,這里設(shè)置了一些其他的屬性,上面都講解了,這里就不去說(shuō)了。。。

WebView加載錯(cuò)誤顯示缺省頁(yè)面

private java.lang.String mUrl = "https://google.com/";
    private WebView mWb;
    private ProgressBar progressBar;
    private java.lang.String mErrorUrl = "file:///android_asset/test.html";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWb = findViewById(R.id.wb);

        progressBar = findViewById(R.id.pb_progress);
        progressBar.setMax(100);

        setWebView(mWb);
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void setWebView(WebView wb) {
        WebSettings settings = wb.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setPluginState(WebSettings.PluginState.ON);
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(true);
        settings.setSupportZoom(true);

        wb.loadUrl(mUrl);
        wb.setWebViewClient(new WebViewClient() {
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                view.loadUrl(String.valueOf(request.getUrl()));
                return true;
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
                super.onReceivedHttpError(view, request, errorResponse);
                // 這個(gè)方法在6.0才出現(xiàn)
                int statusCode = errorResponse.getStatusCode();
                System.out.println("onReceivedHttpError code = " + statusCode);
                if (404 == statusCode || 500 == statusCode) {
                    view.loadUrl("about:blank");// 避免出現(xiàn)默認(rèn)的錯(cuò)誤界面
                    view.loadUrl(mErrorUrl);
                }
            }

            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                // 斷網(wǎng)或者網(wǎng)絡(luò)連接超時(shí)
                if (error.getErrorCode() == ERROR_HOST_LOOKUP || error.getErrorCode() == ERROR_CONNECT || error.getErrorCode() == ERROR_TIMEOUT) {
                    view.loadUrl("about:blank"); // 避免出現(xiàn)默認(rèn)的錯(cuò)誤界面
                    view.loadUrl(mErrorUrl);
                }
            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                super.onReceivedError(view, errorCode, description, failingUrl);
                // 斷網(wǎng)或者網(wǎng)絡(luò)連接超時(shí)
                if (errorCode == ERROR_HOST_LOOKUP || errorCode == ERROR_CONNECT || errorCode == ERROR_TIMEOUT) {
                    view.loadUrl("about:blank"); // 避免出現(xiàn)默認(rèn)的錯(cuò)誤界面
                    view.loadUrl(mErrorUrl);
                }
            }
        });

        wb.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                Log.e("done", "onProgressChanged: " + newProgress);
                progressBar.setProgress(newProgress);
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                // android 6.0 以下通過(guò)title獲取
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                    if (title.contains("404") || title.contains("500") || title.contains("Error")) {
                        view.loadUrl("about:blank");// 避免出現(xiàn)默認(rèn)的錯(cuò)誤界面
                        view.loadUrl(mErrorUrl);
                    }
                }
            }
        });
    }

因?yàn)閃ebView引起了google的重視,所以版本之間存在很多差異,所以這里區(qū)分了很多版本的問(wèn)題,上面都有相應(yīng)的注解!其實(shí)就是在斷網(wǎng)或者網(wǎng)絡(luò)重連的時(shí)候添加了相應(yīng)的錯(cuò)誤頁(yè)面,防止用戶看見(jiàn)那個(gè)難看的斷網(wǎng)頁(yè)面。增加用戶的體驗(yàn)!

WebView與JS交互的實(shí)現(xiàn)

這里先貼一段測(cè)試的js代碼,下面會(huì)用到:

<html>
<head>
    <meta charset="utf-8">
    <title>App調(diào)用js的代碼</title>

    <script>
    // Android需要調(diào)用的方法
    function callJS(){
       console.log("你看我在哪出來(lái)~~~");
    }
    function callAndroid(){
       // 由于對(duì)象映射,所以調(diào)用test對(duì)象等于調(diào)用Android映射的對(duì)象
       test.hello("js調(diào)用了android中的hello方法");
    }
    </script>
</head>
<body>
<h1>假裝這個(gè)一個(gè)頁(yè)面</h1>
<button type="button" id="button1" onclick="callAndroid()"></button>
</body>
</html>

1. 原生代碼調(diào)用js中的代碼

這里可以有兩種實(shí)現(xiàn)方案:
這里注意一點(diǎn),無(wú)論使用那種方案調(diào)用,前提是一定要有下面的代碼?。。?/p>

        WebSettings settings = mWb.getSettings();
        settings.setJavaScriptEnabled(true);//允許相應(yīng)js代碼
  • 通過(guò)loadUrl("javascript:callJS()")調(diào)用js中的代碼,但是會(huì)刷新相應(yīng)的頁(yè)面(這里面callJS是上面function的方法名稱)

  • 通過(guò)evaluateJavascript(String script, ValueCallback<String> resultCallback)的callBack進(jìn)行調(diào)用相應(yīng)的方法(這個(gè)處理效率高,但是這個(gè)方法是在API19才可以使用的,所以一般在使用的時(shí)候通過(guò)判斷版本兩個(gè)一起使用!?。。?/p>

整體的使用代碼如下:

        if (Build.VERSION.SDK_INT > 18) {
            mWb.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                    Log.e("done", "onReceiveValue: " + value);
                }
            });
        } else {
            mWb.loadUrl("javascript:callJS()");
        }

這樣既解決了效率的問(wèn)題也解決了版本的問(wèn)題。

2. 原生代碼調(diào)用js中的代碼

這里最常用的方式就是通過(guò)注釋@JavascriptInterface進(jìn)行調(diào)用,但是看了Carson_Ho的文章說(shuō)這里有漏洞,但是說(shuō)4.2就沒(méi)有這種漏洞了,所以沒(méi)有去研究,感覺(jué)現(xiàn)在一般的手機(jī)都應(yīng)該超過(guò)4.2了,如果以后需要適配的時(shí)候在仔細(xì)看一下!??!

  • 步驟1:
    創(chuàng)建一個(gè)類用于給JS提供相應(yīng)的方法;
    class JSMothod {
        @JavascriptInterface
        public void hello(String msg) {
            System.out.println("JS調(diào)用了Android的hello方法");
        }
    }

這里有一點(diǎn)需要注意的,就是@JavascriptInterface這個(gè)注解一定要加上,否則對(duì)于4.0一下的手機(jī)可能會(huì)存在問(wèn)題!?。∏杏?。。。

  • 步驟2:
    添加相應(yīng)的調(diào)用方法
addJavascriptInterface(Object object, String name);

這里面的兩個(gè)參數(shù)分別是上面寫(xiě)的那個(gè)類對(duì)象和相應(yīng)js中的方法名;具體的代碼是這樣的。。。

mWb.addJavascriptInterface(new JSMothod(),"test");

這樣就能實(shí)現(xiàn)js調(diào)用Android的代碼了,其實(shí)很簡(jiǎn)單。


基本上上面的內(nèi)容就囊括了Android在使用WebView中的一些常見(jiàn)的使用場(chǎng)景,可能還有些內(nèi)容沒(méi)有想到,如果有什么不明白的,可以在下方給我留言,還希望這些內(nèi)容可以幫到你?。?!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • WebView·開(kāi)車指南 目錄 WebView簡(jiǎn)介 WebView基本使用 WebView常用方法 WebSett...
    南城的人閱讀 4,864評(píng)論 0 19
  • 前言 總結(jié) Android WebView 常用的相關(guān)知識(shí)點(diǎn),令包含以下干貨內(nèi)容分析:Js注入漏洞、WebView...
    無(wú)名小子的雜貨鋪閱讀 70,119評(píng)論 17 169
  • WebView·開(kāi)車指南 目錄 WebView簡(jiǎn)介 WebView基本使用 WebView常用方法 WebSett...
    小莊bb閱讀 3,651評(píng)論 3 25
  • Tips 由于WebView的用法實(shí)在太多,如果您只是想查詢某個(gè)功能的使用——建議Ctrl+F(Commad+F)...
    BugDev閱讀 7,910評(píng)論 11 109
  • WebView簡(jiǎn)介 String getUrl():獲取當(dāng)前頁(yè)面的URL。 reload():重新reload當(dāng)前...
    QM閱讀 3,313評(píng)論 0 52

友情鏈接更多精彩內(nèi)容