gpt4 book ai didi

android - Main Activity 销毁后不会被垃圾回收,因为它被 InputMethodManager 间接引用

转载 作者:IT老高 更新时间:2023-10-28 21:41:17 37 4
gpt4 key购买 nike

我关注了来自 here 的“避免内存泄漏”文章.

但是,建议的解决方案并不能解决泄漏问题。我在 Windows XP (SDK 2.3.1) 上使用 android 模拟器对此进行了测试。我转储了堆并检查了主要 Activity 仍在堆中(我使用了 MAT)

这就是我所做的:

  1. 使用 HelloWorldActivity 创建 HelloWorld 应用(它没有 subview )
  2. 运行模拟器并启动 HelloWorld 应用。
  3. 点击后退键将其关闭。
  4. 导致 DDMS 中的 gc 和转储堆 <-- 在这里我找到了 HelloWorldActivity 实例。
  5. 'Path to GC Roots' 显示以下路径。

HelloWorldActivity <- PhoneWindow$DecorView <- InputMethodManager

InputMethodManager 是一个单例和三个对引用 HelloWorldActivity 的 DecorView 的引用。

我不明白为什么 InputMethodManager 即使在 Activity 被销毁后仍然引用 DecorView 实例。

有什么方法可以确保主要 Activity 在关闭后被销毁并可以进行GC?

最佳答案

似乎调用 InputMethodManager 的方法 'windowDismissed' 和 'startGettingWindowFocus' 可以解决问题。

类似这样的:

@Override
protected void onDestroy()
{
super.onDestroy();
//fix for memory leak: http://code.google.com/p/android/issues/detail?id=34731
fixInputMethodManager();
}

private void fixInputMethodManager()
{
final Object imm = getSystemService(Context.INPUT_METHOD_SERVICE);

final Reflector.TypedObject windowToken
= new Reflector.TypedObject(getWindow().getDecorView().getWindowToken(), IBinder.class);

Reflector.invokeMethodExceptionSafe(imm, "windowDismissed", windowToken);

final Reflector.TypedObject view
= new Reflector.TypedObject(null, View.class);

Reflector.invokeMethodExceptionSafe(imm, "startGettingWindowFocus", view);
}

反射器代码:

public static final class TypedObject
{
private final Object object;
private final Class type;

public TypedObject(final Object object, final Class type)
{
this.object = object;
this.type = type;
}

Object getObject()
{
return object;
}

Class getType()
{
return type;
}
}

public static void invokeMethodExceptionSafe(final Object methodOwner, final String method, final TypedObject... arguments)
{
if (null == methodOwner)
{
return;
}

try
{
final Class<?>[] types = null == arguments ? new Class[0] : new Class[arguments.length];
final Object[] objects = null == arguments ? new Object[0] : new Object[arguments.length];

if (null != arguments)
{
for (int i = 0, limit = types.length; i < limit; i++)
{
types[i] = arguments[i].getType();
objects[i] = arguments[i].getObject();
}
}

final Method declaredMethod = methodOwner.getClass().getDeclaredMethod(method, types);

declaredMethod.setAccessible(true);
declaredMethod.invoke(methodOwner, objects);
}
catch (final Throwable ignored)
{
}
}

关于android - Main Activity 销毁后不会被垃圾回收,因为它被 InputMethodManager 间接引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5038158/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com