2011-04-24 62 views
13

查看层次结构如下TabActivityActivityGroupsActivitiesInputMethodManager保存对tabhost的引用 - 内存泄漏 - OOM错误

使用MAT我发现TabWidgetTabHost这是由InputMethodManager引用引用,因此TabWidget泄漏。 On随后启动应用程序OutOfMemory错误。

同样我所有的活动也由InputMethodManager引用。

上正常完成应用程序(击中返回键)(关闭我所有的活动组,活动,tabactivity,tabhost和tabwidget被泄露!!申请后),以下是显示在logcat的

WARN/InputManagerService(99):在非聚焦客户[email protected]开始输入(UID = 10052 PID = 1463)

如何从InputMethodManager删除引用.. 。?

事情我想:

A.调用此方法我TabActivity
1. myTabWidget.removeAllViews()
2. myTabWidger.invalidate()

没有运气的onDestroy


回答

1

事情我想:A.叫我TabActivity 1.myTabWidget.removeAllViews()2.myTabWidger.invalidate的这种方法的onDestroy()

当然,它不会工作。在MVC/MVP/MVVM和Android SDK类层次结构中,活动都不是视图。 android.app.Activity不扩展android.view.View

我的同事有类似的内存泄漏问题 - 他以静态方式在TabActivity中声明tabHost(他想从另一个活动访问它,当他没有熟悉Pattern Observer)。我想你已经做了类似的事情。

,终于,我的问题:你为什么要引用活动InputMethodManager(虽然我不知道如何:这是最后一类),而不是InputMethodManager活动?如果你想要InputMethodManager的全局焦点,我可以建议你把它引用到Application类。我们扩展应用类(例如,HostApplication),在这个门面,我们共同声明的东西(SharedPreferences,例如)。在我们写的活动中:

HostApplication application = (HostApplication) getApplication(); 

然后我们从中得到有用的常见东西。

+0

我不指InputMethodManager反正。你能给我提供更多关于“模式观察者”的链接吗? – Mani 2011-10-24 13:29:58

+1

http://en.wikipedia.org/wiki/Observer_pattern 我们创建了一个模型作为Observable(Subject),并且Activities是Observers(他们实现了接口“Observer”)。开始时,活动在模型中注册(我们使用单例,但可以使用服务或应用程序)。如果有一些有趣的事情,可观察的事件触发事件并通知每一位客户。在销毁之前,Activity在Observable中未注册以避免内存泄漏。 Android中大部分内存泄漏的原因非常简单:Context/View/Dialog在某处被声明为静态方法。 – QuickNick 2011-10-25 07:17:52

3

我也遇到了这个问题,我尝试了一些方法来避免它。当我的活动完成时,我尝试用输入法管理器服务中断连接。检查出来:

class MyActivity extend Activity { 
    @Override 
    public void finish() { 
     InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.windowDismissed(mContentView.getWindowToken()); 
     super.finish(); 
    } 
} 

我不确定这是否可以解决这个内存泄漏。现在,它工作正常。你可以试试看。

+1

mContentView,是对tablayout的根视图的引用吗? – Mani 2012-04-17 01:43:03

+0

InputMethodManager.windowDismissed是Android API中的隐藏方法。所以,不,它不能正常工作。为了得到它,你必须使用反射:'((Class.forName(“android.view.inputmethod.InputMethodManager”))。getMethod(“windowDismissed”,IBinder.class))。invoke(null,mContentView.getWindowToken() );' – iamreptar 2014-03-05 21:23:00

1

你确定内存泄漏是真的吗?我有类似的情况,虽然看起来像MAT中的内存泄漏,但由于InputMethodManager的原因,我无法获得TabActivity的两个实例。当然,InputMethodManager似乎保留了垃圾收集的TabActivity。但是,如果这是一个真正的内存泄漏,我不能看到两个TabActivites,然后三个,然后四个?

(仅供参考,我能够看到两个TabActivities在一个点上,但问题是没有InputMethodManager,它是在代码的静态引用)

+0

是的你是对的。 InputMethoManage不做任何事情。问题在于我用于切换选定选项卡的静态引用。在上面的回答中,“QuickNick”提到了如何去除静态引用使用obeserver模式。 – Mani 2013-02-01 04:25:11