常見View特別是WebView引發記憶體洩漏解決辦法
阿新 • • 發佈:2018-12-03
記憶體洩漏是安卓開發中常見的一種情況,其原因本質上是一個生命週期更長的物件持有了一個本該回收物件的引用,幾種具體的表現已經有很多部落格進行了分析,比如全域性/單例物件,集合,內部類,執行緒,資源物件等等。然而,還有一類洩漏,往往是View相關的原始碼層造成的洩漏:
- 比如當一個Drawable被附加到View時,這個View會被設定為這個Drawable的callback,即持有其引用;
- 還有EditText的inputType=’text’在某些版本和機型下也會有記憶體洩漏;
- WebView更是一個容易記憶體洩漏的view。
當然,還有一些其它情況造成的View相關的記憶體洩漏,這裡就不多說了,本文只是記錄一個比較通用的解決方式。
public class ViewUtils {
private static volatile ViewUtils instance;
private ViewUtils() {
}
public static synchronized ViewUtils get() {
if (instance == null) {
instance = new ViewUtils();
}
return instance;
}
//優化記憶體
public void gcViews(View view) {
if (view == null) {
return;
}
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
if (view instanceof WebView) {
ViewParent parent = view.getParent();
if (parent != null) {
((ViewGroup) parent).removeView(view);
}
((WebView) view).removeAllViews();
((WebView) view).destroy();
return;
}
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
gcViews(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
}
如上面程式碼,建立個工具類,然後在合適的位置(一般是activity或者fragment的onDestroy()方法中)呼叫。比如
ViewUtils.get().gcViews(getWindow().getDecorView());