1. 程式人生 > >全面總結WebView遇到的坑及優化

全面總結WebView遇到的坑及優化

AWeiLoveAndroid

連結:

https://www.jianshu.com/p/2b2e5d417e10

本文由作者授權釋出。

關於WebView,是開發過沖不可避免需要打交道的一個控制元件,可以先通過下面這篇文章做一些瞭解:

  • WebView的基本使用以及Android和js的互動.(本文作者)

    https://www.jianshu.com/p/b9164500d3fb

但是其存在很多坑,需要我們不斷的去發現、修復和優化。

這篇文章講一下WebView遇到的那些坑,帶領各位爬坑。這裡如果有你沒遇到的問題,歡迎留言告訴我,我盡我所能幫你解決。感謝大家支援。

1
那些年那些坑

(1) 為什麼Webview開啟一個頁面,播放一段音樂,退出Activity時音樂還在後臺播放?

解決方案 1:

//銷燬Webview
@Override
protected void onDestroy() {
   if (mWebview != null) {
       mWebview.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
       mWebview.clearHistory();
       ((ViewGroup) mWebview.getParent()).removeView(mWebview);
       mWebview.destroy();
       mWebview = null
;
   }
   super.onDestroy();
}

還有別問我為什麼要移除,等你Error: WebView.destroy() called while still attached!之後你就知道了。

 解決方案 2:

@Override
protected void onPause() {
  h5_webview.onPause();
  h5_webview.pauseTimers();
  super.onPause();
}
@Override
protected void onResume() {
  h5_webview.onResume();
  h5_webview.resumeTimers
();
  super.onResume();
}

Webview的onPause()方法官網是這麼解釋的:

Does a best-effort attempt to pause any processing that can be paused safely, such as animations and geolocation. Note that this call does not pause JavaScript. To pause JavaScript globally, use  pauseTimers(). To resume WebView, call onResume().  

【翻譯:】通知核心嘗試停止所有處理,如動畫和地理位置,但是不能停止Js,如果想全域性停止Js,可以呼叫pauseTimers()全域性停止Js,呼叫onResume()恢復。

(2) 怎麼用網頁的標題來設定自己的標題欄?

解決方案:

WebChromeClient mWebChromeClient = new WebChromeClient() {    
   @Override    
   public void onReceivedTitle(WebView view, String title) {    
       super.onReceivedTitle(view, title);    
       txtTitle.setText(title);    
   }    
};  
mWedView.setWebChromeClient(mWebChromeClient());

注意事項:

  • 可能當前頁面沒有標題,獲取到的是null,那麼你可以在跳轉到該Activity的時候自己帶一個標題,或者有一個預設標題。

  • 在一些機型上面,Webview.goBack()後,這個方法不一定會呼叫,所以標題還是之前頁面的標題。那麼你就需要用一個ArrayList來保持載入過的url,一個HashMap儲存url及對應的title.然後就是用WebView.canGoBack()來做判斷處理了。

(3) 為什麼打包之後JS呼叫失敗(或者WebView與JavaScript相互呼叫時,如果是debug沒有配置混淆時,呼叫時沒問題的,但是當設定混淆後發現無法正常呼叫了)?

解決方案:

在proguard-rules.pro中新增混淆。

-keepattributes *Annotation*  
-keepattributes *JavascriptInterface*
-keep public class org.mq.study.webview.DemoJavaScriptInterface{
  public <methods>;
}
#假如是內部類,混淆如下:
-keepattributes *JavascriptInterface*
-keep public class org.mq.study.webview.webview.DemoJavaScriptInterface$InnerClass{
   public <methods>;
}

其中org.mq.study.webview.DemoJavaScriptInterface 是不需要混淆的類名

(4) 5.0 以後的WebView載入的連結為Https開頭,但是連結裡面的內容,比如圖片為Http連結,這時候,圖片就會載入不出來,怎麼解決?

原因分析:

原因是Android 5.0上Webview預設不允許載入Http與Https混合內容:

解決方案:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
   //兩者都可以
   webSetting.setMixedContentMode(webSetting.getMixedContentMode());
   //mWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}

 引數說明:

  • MIXED_CONTENT_ALWAYS_ALLOW 允許從任何來源載入內容,即使起源是不安全的;

  • MIXED_CONTENT_NEVER_ALLOW 不允許Https載入Http的內容,即不允許從安全的起源去載入一個不安全的資源;

  • MIXED_CONTENT_COMPLTIBILITY_MODE 當涉及到混合式內容時,WebView會嘗試去相容最新Web瀏覽器的風格;

另外:在認證證書不被Android所接受的情況下,我們可以通過設定重寫WebViewClient的onReceivedSslError方法在其中設定接受所有網站的證書來解決,具體程式碼如下:

webView.setWebViewClient(new WebViewClient() {
       @Override
       public void onReceivedSslError(WebView view,
               SslErrorHandler handler, SslError error)
{
           //super.onReceivedSslError(view, handler, error);注意一定要去除這行程式碼,否則設定無效。
           // handler.cancel();// Android預設的處理方式
           handler.proceed();// 接受所有網站的證書
           // handleMessage(Message msg);// 進行其他處理
       }
});

(5) WebView呼叫手機系統相簿來上傳圖片,開發過程中發現在很多機器上無法正常喚起系統相簿來選擇圖片。怎麼解決?

 原因分析:

因為Google攻城獅們對setWebChromeClient的回撥方法openFileChooser做了多次修改,5.0以下openFileChooser有幾種過載方法,在5.0以上將回調方法該為了onShowFileChooser。

解決方案

為了相容各個版本,我們需要對openFileChooser()進行過載,同時針對5.0及以上重寫onShowFileChooser()方法:

上一段示例程式碼,給大家看看:

public class MainActivity extends AppCompatActivity {
private ValueCallback<Uri> uploadMessage;
private ValueCallback<Uri[]> uploadMessageAboveL;
private final static int FILE_CHOOSER_RESULT_CODE = 10000;
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   WebView webview = (WebView) findViewById(R.id.web_view);
   assert webview != null;
   WebSettings settings = webview.getSettings();
   settings.setUseWideViewPort(true);
   settings.setLoadWithOverviewMode(true);
   settings.setJavaScriptEnabled(true);
   webview.setWebChromeClient(new WebChromeClient() {
       //  android 3.0以下:用的這個方法
       public void openFileChooser(ValueCallback<Uri> valueCallback) {
           uploadMessage = valueCallback;
           openImageChooserActivity();
       }
       // android 3.0以上,android4.0以下:用的這個方法
       public void

相關推薦

全面總結WebView遇到的優化

:AWeiLoveAndroid連結:https://www.jianshu.com/p/2b2e5d417e10本文由作者授權釋出。關於WebView,是開發過沖不可避免需要打交道的一個控制元件,可以先通過下面這篇文章做一些瞭解:WebView的基本使用以及Android和

Android WebView開發問題優化彙總

我們在native與網頁相結合開發的過程中,難免會遇到關於WebView一些共通的問題。就我目前開發過程中遇到的問題以及最後得到的優化方案都將在這裡列舉出來。有些是老生常談,有些則是個人摸索得出解決方法。下面就是整理得到的些乾貨。 1.加快HTML網頁裝載完成的速度 預設情況

總結Pyinstaller的終極解決方法

一. 首先要有個穩定環境 下面是博主經測試的覺得坑比較少的環境搭配 Python3.4 + PyQt5.4 + Pyinstaller3.2.1 Python3.5 + PyQt5.8 + Pyi

<canvas合成海報>所問題解決方案總結

設置 iphone 出現問題 保存 白屏 全屏 分享 ase .get 最近做了一個用canvas合成海報圖片的移動端項目,由於一點canvas基礎都沒有,所以去網上搜了一位前輩的demo,但是開發過程中遇到了很多問題,現將所遇問題及解決方法總結如下: 1、移動端c

Xcode9.0+appium1.6.5真機環境運行app知多少

xc0de9.0 appium1.6.5 真機測試app ios app真機測試 ios app自動化測試 Mac下把appium自動化環境搭建好後,進行真機測試時會碰到相當多的坑, 下面給大家一一列出來並附上解決方法。 一、selenium.common.exceptions.WebDr

ionic開發遇到的總結

顯示 for 點擊 nod 類型 第三方 providers node 推出 前言 ionic是一個用來開發混合手機應用的,開源的,免費的代碼庫。可以優化html、css和js的性能,構建高效的應用程序,而且還可以用於構建Sass和AngularJS的優化。ionic會是

兄弟連區塊鏈教程btcpool礦池源碼分析核心機制總結優化思考

tcp dup 最大 啟動 清除 延時 超時 too 文件名 btcpool礦池-核心機制總結及優化思考 核心機制總結 ①gbtmaker 監聽Bitcoind ZMQ中BITCOIND_ZMQ_HASHBLOCK消息,一有新塊產生,將立即向kafka發送新Gbt 另默認

SpringBoot | 總結 | JPA

null 文件中 ces pla exceptio cannot style pan jdbc 1.   Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot

Flutter填全面總結

版權宣告:本文首發在公眾號Flutter那些事,未經授權,嚴禁轉載。 Flutter是一個新的跨平臺開發的工具,博主也玩了一段時間,一步步的踩著坑摸石頭過河,這其中受盡了各種各樣的坑,各種谷歌,stackoverflow,Flutter官網等查資料,然而有些問題還是不能及時解決,於是就自己嘗試著慢慢的摸索除

Loadrunner 呼叫 Webservice 介面 進行 效能測試 時的方法優化總結

1.Webservice                       協議指令碼編寫流程 下面介紹使用 Loadrunner 呼叫 Webservice 介面 通用的流程與方法。 1.1 新建指令碼,選擇 "Webservice" 協議 1.2 選擇 Manag

快速排序兩種方式實現優化總結

 今天看了快速排序,現在對自己的已知的方法進行總結,歡迎拍磚。         快速排序被認為是20世紀十大演算法之一,在排序中,快速排序其實就是我們前面認為最慢的氣泡排序的升級,它們都屬於交換排序類。即快排也是通過不斷比較和移動交換來實現排序的,不過它的實現,增大了記

webview全面總結(二)全面介紹webview用法

簡單介紹 為了方便開發者實現在app內展示網頁並與網頁互動的需求,Android SDK提供了WebView元件 它有如下功能: 顯示和渲染Web頁面 直接使用html檔案(網路上或本地assets中)作佈局 可和JavaScript互動呼叫 Web

WebView詳解使用說明;(android外殼專案總結版)

最近做了一個關於webview寫安卓的殼,套HTML5的應用,雖然整個寫下來後,到了目前的進度,程式碼量不多,共有1000多行,但是整個殼的設計思想和實現思路還是當初查了很久的。所以寫下來,以備後續檢視和分享。 這個webview的殼目前實現的功能我將從三方面說明並總結。

Android開發之UI佈局優化全面總結

Android開發最常見的問題之一是螢幕碎片化太嚴重,所以我們在寫佈局的時候儘量不能適應硬編碼去佈局。 佈局優化在開發過程中起到至關重要的作用。 1.合用weightSum屬性和layout_weig

關於webview的載入快取的總結

1.WebView的介紹     webview是Android中直接載入html頁面的控制元件,它為webApp帶來了新生命。那麼,他的出現也伴隨著很多問題的產生;今天就webview的載入及快取方

XLua總結(不定期更)

1.NGUI通過lua層為按鈕設定lua中點選回撥方法時,需要把儲存當前回撥事件的指令碼記錄到list中,並在該LuaEnv Dispose()之前將所有onClick = null,否則會導致xlua丟擲”try to dispose a LuaEnv wit

OO設計原則 -- OO設計的原則設計過程的全面總結

前面發表了5篇OO設計原則的文章,在這裡我將這個5個原則如何在我們設計過程進行應用進行一下總結, 這是我通過閱讀和學習很多博文和資料後進行的一個梳理和總結,僅供大家來參考。 一.OO(面向物件)的設計基礎 面向物件(OO):就是基於物件概念,以物件為中心,以類和繼承為構造機

Spark面對OOM問題的解決方法優化總結

    Spark中的OOM問題不外乎以下兩種情況 map執行中記憶體溢位shuffle後記憶體溢位    map執行中記憶體溢位代表了所有map型別的操作,包括:flatMap,filter,mapPatitions等。shuffle後記憶體溢位的shuffle操作包括join,reduceByKey

程序員筆記|全面解析Oracle等待事件的分類、發現優化

ref 網絡問題 消失 upload 重新 性能 技術分享 enc ota 一、等待事件由來 大家可能有些奇怪,為什麽說等待事件,先談到了指標體系。其實,正是因為指標體系的發展,才導致等待事件的引入。總結一下,Oracle的指標體系,大致經歷了下面三個階段: 以命中率為主

Android進階——效能優化之記憶體洩漏和記憶體抖動的檢測優化措施總結(七)

上一篇Android進階——效能優化之記憶體管理機制和垃圾回收機制(六)簡述了Java記憶體管理模型、記憶體分配、記憶體回收的機制