解決android中EditText導致的內存泄漏問題
阿新 • • 發佈:2018-11-02
大量 can eset efs extends attribute 自定義 lec hint 開發中用到了LeankCanary,在一個簡單的頁面中(例如 :僅僅 包含Edittext),也會導致內訓泄漏,為此,我在網上找了大量資料,最終解決。
例如一個布局:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
例如一個布局:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="12dp" android:background="@null" android:hint="4-20位不包含特殊字符" android:textSize="15dp" />
<LinearLayout>
以上會導致內存泄漏,是由於EditText引用了Activity的context的原因,在Activity銷毀的時候,
由於Edittext持有對Activity的context的引用,導致Activity無法正常回收。
解決辦法:重寫EditText,將對Activity中Context的引用,改為對ApplicationContext的引用。
代碼如下:
@SuppressLint("AppCompatCustomView")
public class BaseEditText extends EditText {
private static java.lang.reflect.Field mParent; static { try { mParent = View.class.getDeclaredField("mParent"); mParent.setAccessible(true); } catch (NoSuchFieldException e) { e.printStackTrace(); } } public BaseEditText(Context context) { super(context.getApplicationContext()); } public BaseEditText(Context context, AttributeSet attrs) { super(context.getApplicationContext(), attrs); } public BaseEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context.getApplicationContext(), attrs, defStyleAttr); } @SuppressLint("NewApi") public BaseEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context.getApplicationContext(), attrs, defStyleAttr, defStyleRes); } @Override protected void onDetachedFromWindow() { try { if (mParent != null) mParent.set(this, null); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } super.onDetachedFromWindow(); }
}
然後xml中的布局引用自定義的EditText:
<包名.路徑.BaseEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:background="@null"
android:hint="4-20位不包含特殊字符"
android:textSize="15dp" />
另外,由於LinearLayout獲取了焦點,也可能會導致內存的泄漏,
需要在Activity中的onDestroy裏清除掉焦點:
LinearLayout.clearFocus();
再次測試,問題解決!
感謝 https://www.jianshu.com/p/e1b41fb80cdc 文章的啟發。
解決android中EditText導致的內存泄漏問題