- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 MemoryAnalyzer 工具来查找我的 Android 应用程序中的内存泄漏。所以我运行我的应用程序,访问所有 Activity ,然后按返回键直到我到达桌面。然后我使用 DDMS 获取内存转储(按了几次 Cause GC)。
然后我使用 OQL 查询select * from instanceof android.app.Activity
来查找泄漏 Activity ,然后按Merge Shortest Path to GC Roots -> exclude all phantom/weak/泄漏对象上的软/等引用。我这里有这张照片:
所以系统中的某个地方似乎有一个静态对象BubblePopupHelper.sHelper
,它保留了对我 Activity 中的EditText
View 的引用,导致整个 Activity 泄漏!但是这个 BubblePopupHelper
是什么?我在 official docs 中找不到关于此类的任何信息。 .以及如何防止我的 Activity 由于被这个奇怪的对象引用而保留在内存中?
我在运行 API19 的 LG L40 设备上进行测试
最佳答案
我的泄漏检测工具会定期报告同样的泄漏情况,而且仅来自 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 的私有(private) API。这是 LG 引入的内存泄漏。
据我所知,重点 EditText 使用 BubblePopupHelper,可能是为了显示一些复制/粘贴弹出窗口或文本句柄。由于一次只有一个焦点编辑文本,因此他们将助手设为单例,并保留对最新焦点编辑文本的引用。
这意味着整个 Activity 及其整个 View 层次结构将泄漏,直到另一个编辑文本获得焦点。
你怎么解决这个问题?遗憾的是,这是 SDK 代码,因此虽然这可能会在 LG 的 future 版本中修复,但总会有一些用户遇到该错误。
虽然这个错误当然不是你的错,但它仍然是一个内存泄漏,它可能会导致 OutOfMemory 错误增加。因此,值得尝试修复它,
有一种方法,但它并不漂亮。当 Activity 被销毁时,您可以使用反射来清除泄漏。例如,一种方法可能是清除 sHelper 字段,或者另一种方法是清除 helper 上的 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) {
}
}
});
}
});
}
关于android - 由于 android.widget.BubblePopupHelper 导致的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27267071/
所以我在调试时注意到似乎有一个标签在我的应用程序中重复出现,标题为“BubblePopupHelper”,文本为:“isShowingBubblePopup : false” 日志截图 据我所知,我没
我正在使用 MemoryAnalyzer 工具来查找我的 Android 应用程序中的内存泄漏。所以我运行我的应用程序,访问所有 Activity ,然后按返回键直到我到达桌面。然后我使用 DDMS
我的应用每秒向 logcat 发送大约 3 次以下消息:D/BubblePopupHelper:isShowingBubblePopup:false 当我关闭应用程序时,消息不再出现。我不确定这是否重
我是一名优秀的程序员,十分优秀!