InputMethodManager holds reference to the tabhost

2020-08-10 08:00发布

问题:

View hierarchy is as follows TabActivity -> ActivityGroups -> Activities.

Using MAT I found that TabWidget is referenced by TabHost which is referenced by InputMethodManager, hence TabWidget is leaked. On Subsequent launch of application OutOfMemory Error is thrown.

Similarly all my activities are also referenced by InputMethodManager. (After closing the application all my activitygroups, activities, tabactivity, tabhost and tabwidget are leaked!!)

On Properly finishing the application (hitting back key), following is shown in logcat

WARN/InputManagerService(99): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@44a87748 (uid=10052 pid=1463)

How to remove the reference from InputMethodManager...?

Thing I tried:

A. Called this method onDestroy of my TabActivity
1. myTabWidget.removeAllViews()
2. myTabWidger.invalidate()

No Luck!


  • Already posted question: Main Activity is not garbage collected after destruction because it is referenced by InputMethodManager indirectly

回答1:

Thing I tried: A. Called this method onDestroy of my TabActivity 1.myTabWidget.removeAllViews() 2.myTabWidger.invalidate()

Of course, it will not work. Activities aren't views neither in MVC/MVP/MVVM nor in Android SDK classes hierarchy. android.app.Activity doesn't extend android.view.View

My colleague had similar problem with memory leaks - he declared tabHost in TabActivity in static way (he wanted to access it from another activity, when he hadn't been familiar with pattern Observer). I think you've made something similar.

And, at last, my question: why do you reference activities in InputMethodManager (though I don't understand how: it's final class) and not InputMethodManager in activities? If you want global focus point for InputMethodManager, I can advice you to put reference of it to Application class. We extend Application class (for example, HostApplication), in this facade we declare common stuff (SharedPreferences, for example). And in the activities we write:

HostApplication application = (HostApplication) getApplication();

Then we get useful common stuff from it.



回答2:

I also met this problem and I tried some way to avoid it. When my activity is finished, I try to cut off the connection with input method manager service. Check it out:

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

I'm not sure whether this could fix this memory leak at all. For now, it works fine. You could take a try.



回答3:

Are you sure the memory leak is real? I have a similar situation, and while it looks like a memory leak in MAT, I can not get two instances of the TabActivity to appear because of the InputMethodManager. Sure, the InputMethodManager seems to keep the TabActivity from garbage collecting. But, if this was a real memory leak, wouldn't I be able to see two TabActivites, then three, then four?

(FYI, I was able to see two TabActivities at one point, but the problem wasn't the InputMethodManager, it was a static reference in the code)