UI組件——WebView使用總結


  • 重點2:h5頁面在Android WebView中的適配問題
    筆者踩過的坑是h5頁面未對移動端做任何適配,而且在h5頁面指定了
    ,導致Android端適配很差,我們Android端在這裏自己搞各種適配的工作,結果還是不理想,其實這個問題理想解決方法是:h5頁面要儘量使用百分比佈局,比如指定width:100%,那麼就能解決多數問題,但是還有一類問題無法解決,h5頁面中的有些文本在移動端顯示的特別小,如果想要正常顯示,那麼在h5的中添加 name=”viewport” content=”width=device-width”來解決;具體爲

  • 重點3:對加載網頁時出現的失敗網頁的處理
    通常情況下,WebView加載網頁如果出現錯誤,那麼錯誤提示便是網頁本身的錯誤提示,這對用戶來說很不友好,因此,爲了給客戶良好的體驗感,我們會把原生的錯誤提示頁面替換爲一個比較友好的提示頁面,具體是什麼頁面可以找設計。要替換原生的錯誤頁面,我們就要知道當頁面發生錯誤時會回調什麼方法,然後我們在那裏做攔截處理,便可以成功替換頁面了。當加載錯誤時會回調onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)和onReceivedHttpError( WebView view, WebResourceRequest request, WebResourceResponse errorResponse),因此我們在這裏做替換就可以了。注意,第一個方法要求api 23,要做一些適配工作,比如,我們可以判斷版本>23時用第一個方法,其他情況下用這個方法:onReceivedError(WebView view, int errorCode,String description, String failingUrl)。

  • 重點4:與js交互
    這是WebView的重中之重,分兩個方向講1:Android調用js,2:js調用Android
    • 1:Android調用js
      android 調用js又分爲兩種情況,一種是無返回值的調用,一種是有返回值的調用。無論哪種情況都需要添加webSettings.setJavaScriptEnabled(true);否則不會生效
      • a:無返回值的交互
        Android調用js無需返回值時直接使用:webview.loadUrl(str);str是需要執行的js語句,UI組件——WebView部分api釋義 這裏已經講過了。
      • b:有返回值的調用
        Android調用js有返回值的方法是在Android4.4(api 19)以後新增的方法:evaluateJavascript(String script, ValueCallback resultCallback);script是即將執行的js語句,resultCallback是執行結果的回調
    • 2:js調用Android
      首先:Android需要提供可調用的方法,這裏以獲取html的寬度爲例:
    //通過與js交互來獲取HTML的寬度
    class JavaScriptToAndroid {
        @JavascriptInterface//必須要記得加上
        public void getWidth(String value) {
            if (value != null) {
                int width = Integer.parseInt(value);
                Toast.makeText(WebViewActivity.this, "width of html is: " + width + "px", Toast.LENGTH_SHORT).show();
            }
        }
    }
  然後設置
 settings.setJavaScriptEnabled(true);
 並將該類注入到js中,並以Android作爲調用的標識
webView.addJavascriptInterface(new JavaScriptToAndroid(), "Android");
 最後在html中調用這個方法,html代碼:
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
            *{
                margin:0;
                padding:0;
            }
            .box{
                width: 100%;
                height:500px;
                background: pink;
                margin:0 auto;
            }

    </style>
</head>
<body>
<div class="box">
    <p>
        <input type="button" id="enter" value="調用Android" onclick="testClick();"/>
    </p>
</div>
</body>
<script>
   function testClick(){
   window.Android.getWidth(document.getElementsByClassName("box")[0].offsetWidth)
   }
</script>
</html>
   至此,交互結束

  • 重點5:埋下的坑

    • 坑1:安全問題
      webView 在api 4.0 到4.2 之間增加了 searchBoxJavaBridge_ 方法,導致webView 存在安全漏洞解決方法是:在4.2 以前的版本不用 addJavascriptInterface 接口,並且在4.0-4.2之間移除searchBoxJavaBridge方法 —>我也是google來的,並未遇到
    public class MyWebView extends WebView{
    
    
    public MyWebView(Context context) {
        super(context);
        removeSearchBoxJavaBridgeInterface();
    }
    
    public MyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        removeSearchBoxJavaBridgeInterface();
    }
    
    public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        removeSearchBoxJavaBridgeInterface();
    }
    
    public MyWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        removeSearchBoxJavaBridgeInterface();
    }
    
    
    private void removeSearchBoxJavaBridgeInterface() {
        if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17) {
            removeJavascriptInterface("searchBoxJavaBridge_");
        }
    }
    
    @Override
    public void addJavascriptInterface(Object object, String name) {
        if (Build.VERSION.SDK_INT >= 17) {
            super.addJavascriptInterface(object, name);
        }
    }
    }
    • 坑2:內存泄漏問題
      @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mMyWebView != null) {
            mMyWebView.stopLoading();
            mMyWebView.getSettings().setJavaScriptEnabled(false);
            ViewGroup parent = (ViewGroup) mMyWebView.getParent();
            parent.removeAllViews();//ViewGroup中的方法
            try {
                mMyWebView.destroy();//銷燬WebView
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    • 坑3:執行js腳本偶發性失敗(尚未解決)
發佈了54 篇原創文章 · 獲贊 17 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章