【问题标题】:Android EditText Memory LeakAndroid EditText 内存泄漏
【发布时间】:2013-08-23 06:30:58
【问题描述】:

很多人注意到活动中的 EditText 持有对活动的强引用,即使它完成后也是如此。要清楚,此 EditText 位于布局内并膨胀,没有设置 Listeners。这只发生在某些设备上,例如三星 Galaxy S4 (Android 4.2.2) 等。许多关于此的帖子仍然没有解决方案。首先是一些有用的帖子。 (最终 GC 会清除它,因此从技术上讲它不是泄漏,但对于内存大的应用程序来说,它需要很长时间并且会导致 OOM)

Android Samsung Memory leak in EditText

Why does EditText retain its Activity's Context in Ice Cream Sandwich

EditText causing memory leak

Possibility of unhandled memory leak

上述解决方案不适用于所有设备。它归结为 Edittext Watcher。我认为可能有解决方案覆盖这个 Watcher,然后有一个函数来清理它 onDestroy()。请在这里提供任何帮助,我已经在这几天了。

这是 MAT 直方图

【问题讨论】:

  • 明确内存泄漏检测设备可以报告“误报”。它有据可查,可能是您无法控制的代码的结果。
  • 是的,这仅与某些手机有关,但是我想找到一种解决方法来更改它,因为具有此功能的手机最终会出现 oom。
  • @MobDev 你找到解决方案了吗?
  • 也许这种解决方法可能对您有所帮助:*.com/a/27231817/1532108

标签: android memory-leaks android-edittext android-textattributes


【解决方案1】:

这是因为EditText引用了Activity的上下文。当Activity被销毁时, Activity 无法正常回收,因为 Edittext 持有对 Activity 上下文的引用。 解决方法:重写EditText,将Activity中对Context的引用改为对ApplicationContext的引用。

说明:

https://programming.vip/docs/solve-the-memory-leak-problem-caused-by-edittext-in-android.html

【讨论】:

    【解决方案2】:

    很长一段时间以来,我都对这个内存泄漏感到困惑。但是最近我找到了两种方法来解决这个问题。

    1. 我发现如果您的 TextView/EditText 具有 android:hint 属性,则不会发生这种情况。所以最简单的方法是给每个 TextView/EditText 一个hint属性。

    2. 最有力的方法是通过TextLine进行反射,找到ChangeWatcher监听器,然后杀死这个监听器。

    【讨论】:

      【解决方案3】:

      我通过将活动上下文更改为应用程序上下文解决了这个问题。

      【讨论】:

        【解决方案4】:

        尝试在 onCreateView() 中为这个特定的 View(包含任何 android:textIsSelectable="true" 组件)使用 Application Context 而不是 Activity Context。

        // Singleton
        class MyApplication extends Application {
            private static MyApplication mApp;
        
            @Override
            public void onCreate() {
                mApp = this;
            }
        
            public static MyApplication getApp() {
                return mApp;
            }
        }
        
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            // Suggested inflater use Activity Context
            // So we must tu use Application Context
            Context context = MyApplication.getApp().getApplicationContext();
            LayoutInflater myLayoutInflater = LayoutInflater.from(context);
        
            View view = myLayoutInflater.inflate(R.layout.my_view, container, false);
            return view;
        }
        

        【讨论】:

        • 如果您为应用使用不同的默认主题并为您的活动使用另一个主题,则使用应用上下文而不是活动上下文来膨胀视图可能会导致不需要的结果。在这种情况下使用new ContextThemeWrapper(getApplicationContext(), R.style.your_activity_theme)。我遇到了更多问题(tex 视图中的链接不起作用或弹出菜单无法打开崩溃)所以这通常是一个坏主意。