我檢漏工具報告相同的泄漏定期,僅LG手機:
object com.squareup.SomeActivity
`-mContext of object android.widget.EditText
`-mView of object android.widget.BubblePopupHelper
`-sHelper of class android.widget.BubblePopupHelper
製造商想改變私有的API引擎蓋下的Android SDK。這是由LG引入的內存泄漏。
從我可以收集的內容來看,聚焦的EditText使用BubblePopupHelper,可能會顯示一些複製/粘貼彈出窗口或文本句柄。由於一次只有一個重點編輯文本,因此他們將幫助器設置爲單例,並保持對最新編輯文本的引用。
因此,這意味着整個活動&其整個視圖層次結構將泄漏,直到另一個編輯文本得到關注。
你怎麼解決這個問題?不幸的是,這是SDK代碼,所以雖然這可能在未來的LG版本中得到修復,但總會有一些用戶出現這種錯誤。
雖然這個錯誤當然不是你的錯,但它仍然是一個內存泄漏,它可能會泄漏增加OutOfMemory錯誤。所以,這是值得嘗試修復它,
有一種方法,但它不漂亮。當活動被破壞時,您可以使用反射來清除泄漏。例如,一種方法可以是清除sHelper字段,或者另一種方法是清除幫助器上的mView字段。無論哪種方式,你應該嘗試在設備上(我現在沒有),看看它是否有效。
private static final Executor backgroundExecutor =
newCachedThreadPool(backgroundThreadFactory("android-leaks"));
public static void fixLGBubblePopupHelper(final Application application) {
backgroundExecutor.execute(new Runnable() {
@Override public void run() {
final Field sHelperField;
try {
Class<?> bubbleClass = Class.forName("android.widget.BubblePopupHelper");
sHelperField = bubbleClass.getDeclaredField("sHelper");
sHelperField.setAccessible(true);
} catch (Exception ignored) {
// We have no guarantee that this class/field exists.
return;
}
application.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacksAdapter() {
@Override public void onActivityDestroyed(Activity activity) {
try {
sHelperField.set(null, null);
} catch (IllegalAccessException ignored) {
}
}
});
}
});
}
我今天發現了這個,也是在一個帶有API19的LG設備上。 @Blackbelt這絕對是一個泄漏,因爲這個活動被破壞了,應該已經被垃圾收集了,但是由於這個靜態字段,它在堆中仍然活着。在我的情況下,我在創建堆轉儲之前打開了一個簡單而小的活動,以便我可以輕鬆識別任何其他活動的泄漏。 – dsh 2016-03-03 19:13:43