我的泄漏检测工具会定期报告相同的泄漏,仅来自 LG 手机:
object com.squareup.SomeActivity
`-mContext of object android.widget.EditText
`-mView of object android.widget.BubblePopupHelper
`-sHelper of class android.widget.BubblePopupHelper
制造商喜欢在底层更改 Android SDK 的私有 API。这是 LG 引入的内存泄漏。
据我所知,重点突出的 EditText 使用 BubblePopupHelper,可能是为了显示一些复制/粘贴弹出窗口或文本句柄。由于一次只有一个焦点编辑文本,因此他们将帮助程序设为单例,并保留对最新焦点编辑文本的引用。
这意味着整个 Activity 及其整个视图层次结构将泄漏,直到另一个编辑文本获得焦点。
你怎么能解决这个问题?遗憾的是,这是 SDK 代码,所以虽然这可能会在 LG 的未来版本中得到修复,但总会有一些用户遇到该错误。
虽然这个错误肯定不是你的错,但它仍然是内存泄漏,它可能会导致 OutOfMemory 错误增加。所以,值得尝试修复它,
有一种方法,但它并不漂亮。当activity被销毁时,可以使用反射来清除泄漏。例如,一种方法可能是清除 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) {
}
}
});
}
});
}