Android開發經驗談:webview記憶體洩漏
看了很多WebView記憶體洩漏的博文,很多文章都有多多少少的問題。
我便在我自己的博文中仔細針對webView記憶體洩漏進行分析。
看這篇文章的人都應該對webview深惡痛絕
怎麼總是釋放不掉呢???
釋放不掉的原因是啥呢???
為啥特麼的總是陰魂不散呢???
答:webView內部的一些執行緒持有activity物件,導致activity無法釋放。繼而記憶體洩漏。
解決:
方案一:退出程式呼叫
System.exit(0);
image.gif
弊:太暴力,只能在程式退出後清除持有。
方案二:activity弱應用持有
private WeakReference<BaseWebActivity> webActivityReference = new WeakReference<BaseWebActivity>(this); bridgeWebView = new BridgeWebView(webActivityReference .get()); bridgeWebView.setLayoutParams(params); container.addView(bridgeWebView); 在銷燬中執行 @Override protected void onDestroy() { super.onDestroy(); //防止webView記憶體洩漏 if (bridgeWebView != null) { //先從父容器中移除webview,然後再銷燬webview ViewParent parent = bridgeWebView.getParent(); if (parent != null) { ((ViewGroup) parent).removeView(bridgeWebView); } bridgeWebView.stopLoading(); // 退出時呼叫此方法,移除繫結的服務,否則某些特定系統會報錯 bridgeWebView.getSettings().setJavaScriptEnabled(false); bridgeWebView.clearHistory(); bridgeWebView.clearView(); bridgeWebView.removeAllViews(); try { bridgeWebView.destroy(); } catch (Throwable ex) { } bridgeWebView = null; this.webActivityReference.clear(); this.webActivityReference = null; } }
image.gif
說明:
看了很多文章,文中大多都建議不在xml中寫webview,都沒有說明原因。主要是xml中建立的webview持有Activity的context物件
方案三:新建程序
缺點:新建程序比較麻煩的在於程序間通訊
還存在如下問題
- 靜態成員和單例模式失效
- 執行緒同步機制失效
- SharedPreferences 可靠性降低
- Application 被多次建立
優點:
增加應用可用的記憶體空間,不與主程序競爭記憶體空間,不使用程序則銷燬。
通訊方式
- AIDL :功能強大,支援程序間一對多的實時併發通訊,並可實現 RPC (遠端過程呼叫)。
- Messenger :支援一對多的序列實時通訊, AIDL 的簡化版本。
- Bundle :四大元件的程序通訊方式,只能傳輸 Bundle 支援的資料型別。
- ContentProvider :強大的資料來源訪問支援,主要支援 CRUD 操作,一對多的程序間資料共享,例如我們的應用訪問系統的通訊錄資料。
- BroadcastReceiver :即廣播,但只能單向通訊,接收者只能被動的接收訊息。
- 檔案共享 :在非高併發情況下共享簡單的資料。
- Socket :通過網路傳輸資料。
例項:
//xml配置activity,在remoteweb程序中 <activity android:name=".WebActivity" android:process=":remoteweb"/>
image.gif