android webview一篇文章全面瞭解(基本使用,url攔截,js跟java交互)

關注微信公衆號:程序員小安,精彩文章按期推送。javascript

1.前言

最近幾年混合應用愈來愈流行,及一部分功能用原生代碼開發,一部分功能用html5實現。那何時用原生何時用網頁呢?不少人第一反應就是常常變化的頁面用網頁開發,避免常常發包,不全對。其實由於網頁使用體驗遠遠不及原生開發,因此通常有如下兩種狀況建議使用網頁代替原生: 1.試水功能 2.相似雙11主會場,這類只在固定時間內使用的功能。css

2.基本使用方法

1)xml佈局:html

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/title_name"
        android:layout_width="match_parent"
        android:layout_height="44dp"
        android:gravity="center"
        android:background="#987654"
        android:text="title"/>

    <ProgressBar
        android:id="@+id/webview_progressbar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="2dp" />

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

</LinearLayout>
複製代碼

2)利用WebSettings設置一些頁面屬性,好比,頁面字體的大小,是否支持js,支持縮小放大,支持本地存儲,支持緩存等。html5

public static void initWebSettings( WebView webView) {
        WebSettings webSettings = webView.getSettings();
        webSettings.setDefaultTextEncodingName("UTF-8");//設置默認爲utf-8
        webSettings.setTextZoom(100);//設置WebView中加載頁面字體變焦百分比,默認100
        //屬性可讓webview只顯示一列,也就是自適應頁面大小,不能左右滑動
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
        } else {
            webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
        }

        //設置此屬性,可任意比例縮放
        webSettings.setUseWideViewPort(false);
        webSettings.setLoadWithOverviewMode(true);

        //頁面支持縮放
        webSettings.setBuiltInZoomControls(false);
        webSettings.setSupportZoom(false);
        webSettings.setDisplayZoomControls(false);
        //設置支持js
        webSettings.setJavaScriptEnabled(true);
        webSettings.setSavePassword(false);
        //設置 緩存模式
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        // 開啓 DOM storage API 功能
        webSettings.setDomStorageEnabled(true);

        webView.setVerticalScrollBarEnabled(false);
        webView.setVerticalScrollbarOverlay(false);
        webView.setHorizontalScrollBarEnabled(false);
        webView.setHorizontalScrollbarOverlay(false);

    }
複製代碼

3)加載內容 (1)加載assets目錄下的本地網頁 通常咱們都是把html文件放在assets目錄下, WebView調用assets目錄下的本地網頁和圖片等資源很是方便,以下代碼所示:java

webView.loadUrl("file:///android_asset/html/intermodulation.html");
複製代碼

(2)加載遠程網頁jquery

webView.loadUrl("http://www.baidu.com/");
複製代碼

(3)使用 LoadData 或者 loadDataWithBaseURL方法加載內容 有時候咱們的webview可能只是html片斷,而不是一個完整的網頁,事實上絕大多數時候都是如此,完整的網頁無需作成應用,而直接在瀏覽器訪問。這種狀況咱們使用 LoadData 或者 loadDataWithBaseURL方法,後者用的最多:android

void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
複製代碼

loadDataWithBaseURL()比loadData()多兩個參數,能夠指定HTML代碼片斷中相關資源的相對根路徑,也能夠指定歷史Url,其他三個參數相同。程序員

這裏主要注意參數baseUrl,baseUrl指定了你的data參數中數據是以什麼地址爲基準的,由於data中的數據可能會有超連接或者是image元素,而不少網站的地址都是用的相對路徑,若是沒有baseUrl,webview將訪問不到這些資源。以下所示:web

String body ="示例:這裏有個img標籤,地址是相對路徑<img src='/uploads/allimg/130923/1FP02V7-0.png' />";
mWebView.loadDataWithBaseURL("http://baidu.com", body, "text/html", "utf-8",null);
複製代碼

若是baseUrl沒有指定爲baidu.com,那麼這張圖片將顯示不出來。瀏覽器


到這裏,基本的webview功能已經可使用了。

3.android應用中攔截js點擊跳轉,替換成跳轉到原生界面。

實際項目中,可能會顯示網頁標題,須要展現加載進度,或者當點擊網頁中一個按鈕或者一個商品,須要跳轉到原生界面,這個時候就須要用到兩個方法: WebViewClient主要用來攔截網頁中的請求,開始,結束請求等操做。

webView.setWebViewClient(new WebViewClient() {

            //返回值:true 不會顯示網頁資源,須要等待你的處理,false 就認爲系統沒有作處理,會顯示網頁資源
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //當url裏面包含webview字段的時候,則跳轉到ShowActivity原生頁面,不然仍是繼續顯示網頁
                //好比:在百度輸入框裏面輸入webview在點擊搜索,再點擊任何有webview字段的連接,
                //則不繼續顯示網頁,而是跳轉到本身定義的原生頁面
                if (!TextUtils.isEmpty(url)
                        && url.contains("webview")) {
                    Intent intent = new Intent(ClickInterceptionActivity.this, ShowActivity.class);
                    intent.putExtra("url", url);
                    startActivity(intent);
                    return true;
                }
                return false;
            }

            //在頁面開始加載時候作一些操做,好比展現進度條
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                webview_progressbar.setVisibility(View.VISIBLE);
                super.onPageStarted(view, url, favicon);
            }
            //在頁面加載完成的時候作一些操做,好比隱藏進度條
            @Override
            public void onPageFinished(WebView view, String url) {
                webview_progressbar.setVisibility(View.GONE);
                super.onPageFinished(view, url);
            }
        });
複製代碼

WebChromeClient主要輔助WebView處理JavaScript的對話框、網站圖標、網站title、加載進度等。

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

            @Override
            public void onReceivedTitle(WebView view, String title) {
                title_name.setText(title);
                super.onReceivedTitle(view, title);
            }

            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                super.onReceivedIcon(view, icon);
            }

        });
複製代碼

效果以下所示:帶有加載進度和標題 這裏寫圖片描述 當在輸入框中webview,並點擊【百度一下】,正常狀況會進入搜索結果網頁,因爲咱們重寫了shouldOverrideUrlLoading方法,對url實現了攔截,則跳轉到原生頁面。 這裏寫圖片描述 這裏寫圖片描述

4.js和Java的交互

除了上面的簡單展現,不少項目中還會有js跟java的雙向交互。

1)js調用android原生方法

1.addJavascriptInterface

webView.addJavascriptInterface(new clickOnJS(), "click");
複製代碼

2.在android中定義待調用方法:

class clickOnJS {
        @JavascriptInterface
        public void OnClick() {
            Toast.makeText(IntermodulationActivity.this, "調用java成功", Toast.LENGTH_SHORT).show();
        }

    }
複製代碼

3.js定義方法去調用java方法。

$(function(){
      $('.payment').click(function(){
            window.click.OnClick();
        });

    });
複製代碼

效果以下圖所示:點擊【js調用java】按鈕,則彈出toast,證實成功調用java原生方法。 這裏寫圖片描述

2)android調用js方法 當點擊android頁面上某個按鈕的時候,改變js頁面的內容,其實就是android原生給js傳值。 1.點擊標題,則調用js方法

title_name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //調用js方法
                webView.loadUrl("javascript:setcontent(2)");
            }
        });
複製代碼

2.js代碼實現,修改cr的值

function setcontent(content){
          $('.num ,.cr').text(content);
        }
複製代碼

效果以下圖所示:點擊標題,則調用js的setcontent方法,【待修改點】變成【2】,則證實成功調用java原生方法。 這裏寫圖片描述 這裏寫圖片描述

5.部分源碼

1)攔截js點擊跳轉關鍵代碼類:

public class ClickInterceptionActivity extends Activity {

    private TextView title_name;

    private ProgressBar webview_progressbar;

    private WebView webView;

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

        initView();
        initWebViewSettings();
    }


    /**
     * 初始化佈局組件
     */
    private void initView() {
        title_name = (TextView) findViewById(R.id.title_name);
        webview_progressbar = (ProgressBar) findViewById(R.id.webview_progressbar);
        webView = (WebView) findViewById(R.id.webview);

    }

    /**
     * 初始化webview配置
     */
    private void initWebViewSettings() {
        WebViewSettings.initWebSettings(webView);
        webView.setWebViewClient(new WebViewClient() {

            //返回值:true 不會顯示網頁資源,須要等待你的處理,false 就認爲系統沒有作處理,會顯示網頁資源
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //當url裏面包含webview字段的時候,則跳轉到ShowActivity原生頁面,不然仍是繼續顯示網頁
                //好比:在百度輸入框裏面輸入webview在點擊搜索,再點擊任何有webview字段的連接,
                //則不繼續顯示網頁,而是跳轉到本身定義的原生頁面
                if (!TextUtils.isEmpty(url)
                        && url.contains("webview")) {
                    Intent intent = new Intent(ClickInterceptionActivity.this, ShowActivity.class);
                    intent.putExtra("url", url);
                    startActivity(intent);
                    finish();
                    return true;
                }
                return false;
            }

            //在頁面開始加載時候作一些操做,好比展現進度條
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                webview_progressbar.setVisibility(View.VISIBLE);
                super.onPageStarted(view, url, favicon);
            }
            //在頁面加載完成的時候作一些操做,好比隱藏進度條
            @Override
            public void onPageFinished(WebView view, String url) {
                webview_progressbar.setVisibility(View.GONE);
                super.onPageFinished(view, url);
            }
        });
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                webview_progressbar.setProgress(newProgress);
                super.onProgressChanged(view, newProgress);
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                title_name.setText(title);
                super.onReceivedTitle(view, title);
            }

            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                super.onReceivedIcon(view, icon);
            }

        });
        webView.loadUrl("http://www.baidu.com/");
    }

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

複製代碼

2)js跟java交互關鍵類:

public class IntermodulationActivity extends Activity {

    private TextView title_name;

    private ProgressBar webview_progressbar;

    private WebView webView;

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

        initView();
        initWebViewSettings();
    }


    /**
     * 初始化佈局組件
     */
    private void initView() {
        title_name = (TextView) findViewById(R.id.title_name);
        webview_progressbar = (ProgressBar) findViewById(R.id.webview_progressbar);
        webView = (WebView) findViewById(R.id.webview);

        title_name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //調用js方法
                webView.loadUrl("javascript:setcontent(2)");
            }
        });
    }

    /**
     * 初始化webview配置
     */
    private void initWebViewSettings() {
        WebViewSettings.initWebSettings(webView);
        webView.addJavascriptInterface(new clickOnJS(), "click");
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (!TextUtils.isEmpty(url)
                        && url.contains("webview")) {
                    Intent intent = new Intent(IntermodulationActivity.this, ShowActivity.class);
                    intent.putExtra("url", url);
                    startActivity(intent);
                }
                return false;
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                webview_progressbar.setVisibility(View.VISIBLE);
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                webview_progressbar.setVisibility(View.GONE);
            }
        });
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                webview_progressbar.setProgress(newProgress);
                super.onProgressChanged(view, newProgress);
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                title_name.setText(title);
                super.onReceivedTitle(view, title);
            }

            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                super.onReceivedIcon(view, icon);
            }

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

    class clickOnJS {
        @JavascriptInterface
        public void OnClick() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Toast.makeText(IntermodulationActivity.this, "調用java成功", Toast.LENGTH_SHORT).show();
        }

    }

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

3)js實現類:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;"
          name="viewport"/>
    <title>js和java交互(點擊,點擊)</title>
    <link href="images/styles.css" rel="stylesheet" type="text/css">
    <script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
</head>

<body class="mbg1">

<div class="paybox pay2box">java修改js==============     <span class="cr">待修改點</span></div>

<span class="payment"><a href="#">js調用java</a></span>
<script>

    $(function(){
      $('.payment').click(function(){
            window.click.OnClick();
        });

    });
     function setcontent(content){
          $('.num ,.cr').text(content);
        }

</script>
</body>
</html>

複製代碼

6.demo下載地址:

關注下方公衆號,留言回覆源碼便可獲取。


若有錯誤歡迎指出來,一塊兒學習。 在這裏插入圖片描述

相關文章
相關標籤/搜索