Android 關於WebView的使用技巧小解

weixin_34075551發表於2017-12-01

前言

WebView是安卓中的一個元件,它的作用,是可以用來載入Web網頁,整合在android手機系統的app,則主要是載入h5的頁面,下面就介紹一下,關於這個元件的一些常用小技巧。

1.載入url

webView.loadUrl(url);

注:webView.loadUrl(url),其中的url,可以載入三種不同的型別,可以是一個網頁,也可以apk包中的html頁面,還可以是手機本地的html頁面。

2.載入進度條

由於webview載入的h5頁面,非原生控制元件,若是內容較多時,載入的時間,可能會較長,為了緩解使用者等待的焦躁,可以加入一個進度條的設定,從而讓使用者知曉,這個頁面大約還有多久能載入出來,效果如下圖所示:

9063369-23d8f25e5461772d.png
image.png

而要實現這個效果程式碼如下:

2.1佈局:

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

2.2程式碼:

 @BindView(R.id.myProgressBar)
 ProgressBar bar;
 webView.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (newProgress == 100) {
                    bar.setVisibility(View.INVISIBLE);
                } else {
                    if (View.INVISIBLE == bar.getVisibility()) {
                        bar.setVisibility(View.VISIBLE);
                    }
                        bar.setProgress(newProgress);
                    }
                    super.onProgressChanged(view, newProgress);
            });

注:1.佈局中,progressPar的style屬性,可以設定進度條的樣式,若是不設定,預設為圓形;
2.setWebChromeClient下的 onProgressChanged就是監控原本用於webview來監控進度條的,所以,這個進度條是實時監控的真進度條,而不是假進度條。

3.與JS方法的互動

因為使用WebView所載入的是一個h5的網頁,所以,想要對頁面進行操作的話,最方便的辦法,就是後臺設定js的方法,前端去呼叫互動。

3.1在JS中呼叫本地java方法

程式碼如下:

     //設定WebView支援JavaScript
     webView.getSettings().setJavaScriptEnabled(true);
     //在js中呼叫本地java方法
     webView.addJavascriptInterface(new NativeModel(mContext), "NativeModel");
     String id0;
     String post_id0;
     /**
      * js呼叫方法
      */
     private class NativeModel {
        private Context mContext;

        public NativeModel(Context context) {
            this.mContext = context;
        }

        @JavascriptInterface
        public void reply(String id, String post_id) {
            id0 = id;
            post_id0 = post_id;
        }
    }

注:1.NativeModel,這個應該是約定俗稱的方法名;
2.js呼叫方法,一、是需要一個構造方法,而則是必要帶上註解@JavascriptInterface;
3.程式碼中的reply方法,是我專案中的app,後臺自定義的,而引數id與post_id,前者指代的頁面id,後者指代條目id,從而對頁面條目,進行回覆處理;
最終效果如下圖所示:


9063369-97e7b68c230a00f5.png
image.png

點選右下角的回覆圖示,可以獲取到id與post_id,再配合上自家回覆框的顯示隱藏程式碼,就可以彈出對應的回覆框,各位讀者,可以根據自家app的需求,進行各自的互動實現。

3.2在java中截獲JS的alert()方法,獲取裡面的內容

JS的aler()方法,其實就是一個彈窗方法,java有方法可以截獲這個彈窗方法,獲取其中的內容,從而進行一些操作。
實現程式碼如下:

     //新增客戶端支援
     webView.setWebChromeClient(new WebChromeClient(){
         @Override
         public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
             Message obtain = Message.obtain();
             obtain.obj = message;
             obtain.what = HAND_SHARE;
             handler.sendMessage(obtain);
             result.confirm();
             return true;
         }
     });
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case HAND_SHARE:
                    String result = (String) msg.obj;
                    ShareBean shareBean = new Gson().fromJson(result,ShareBean.class);
                    String title = shareBean.getTitle();
                    String content = shareBean.getContent();
                    title0 = title;
                    content0 = content;
                    break;
            }
        }
    };

注:1.利用onJsAlert方法,截獲其中的message,return true表示消耗掉alert彈窗事件,若是return false會彈出一個訊息框;
2.其中的message,其實就是一個String字串,而這裡,比較特殊的是,這個字串還是一個json串(這個json串是與後臺定義的,不一定非要是json串),從而可以自定義一個bean類,對其進行解析,解析之後,可以獲取對應的引數,在我開發的app中,獲取的是這個頁面的title(標題)以及content(內容),從而點選上圖中的右上角,分享的圖示,實現一些第三方的分享操作。

4.關於WebView一些餘下的補充說明

先放一段程式碼:

        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.LOLLIPOP){       //解決http頭像載入不出的問題
            webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        webView.setWebViewClient(new WebViewClient() {           //解決測試環境https證照不信任的問題

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


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

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                //當頁面載入完成時,呼叫方法,獲取需要分享的連結和資訊
                webView.loadUrl("javascript:alert(share())");
            }
        });

分部分拆解:

  if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.LOLLIPOP){       
            webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }

在5.0以上的系統,http的頭像若是載入不出,可以使用這段程式碼解決;

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

這個方法,可以跳過https環境的檢測,可以讓https的頭像載入出來,也可以解除一些證照不信任的問題;

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

這個方法,可以檢測當前載入的h5頁面,地址有沒有發生改變;

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        //當頁面載入完成時,呼叫方法,獲取需要分享的連結和資訊
        webView.loadUrl("javascript:alert(share())");
    }

這個方法,可以檢測h5頁面是否載入完畢,值得一提的是,上述3.2中獲取分享資訊的方法,需要在這個頁面載入完全之後呼叫: webView.loadUrl("javascript:alert(share())");否則有可能會出現差錯。

後記

學無止境,關於WebView這個元件,我也只使用過幾次,瞭解的並不多,歡迎各位讀者,補充說明,共同進步,在android技術開發這條道路上,長成自己想象的樣子。

相關文章