TextView未删除的ChangeWatchers导致内存泄漏

时间:2012-04-19 22:44:22

标签: android

我们有活动和碎片泄漏,并将原因追溯到TextViews上似乎未移除的ChangeWatchers。

方案: 活动A启动活动B. B的布局中有一个textPassword EditText字段。活动B结束。

HPROF转储显示活动B仍有一个实例。其gcroot路径如下:

test.maa.LoginActivity
'- mContext android.widget.EditText 
   '- this$0 android.widget.TextView$ChangeWatcher 
      '- [1] java.lang.Object[13] 
         '- mSpans android.text.SpannableStringBuilder 
            '- mSource android.text.method.PasswordTransformationMethod$PasswordCharSequence 
               '- mText android.text.MeasuredText 
                  '- mMeasured android.text.StaticLayout 
                     '- sStaticLayout class android.text.DynamicLayout 

如果您将Linkify.addLinks链接到TextView,也会发生这种情况。

有没有办法清理活动B?

3 个答案:

答案 0 :(得分:1)

据我所知,这似乎是Android中与TextView ChangeWatcher和Linkify或Html.fromHtml可跨越字符串相关的错误。通过在我的活动的onDestroy()中调用setText(null),我能够解决这个问题。可能还有其他可行的解决方法,但我无法找到有关泄漏的任何进一步信息。

答案 1 :(得分:0)

对于我们来说,问题是由PasswordTransformationMethod中的EditText引起的。专门为我们准备的,它包装在TextInputLayout中,因此我们必须像这样切换它(此代码在Fragment#onDestroyView()中):

        TextInputLayout passwordTextInputLayout = root.findViewById(R.id.textInputLayout);
        if (passwordTextInputLayout.isPasswordVisibilityToggleEnabled())
            passwordTextInputLayout.setPasswordVisibilityToggleEnabled(false);

发生在androidx.appcompat:appcompat:1.0.0

答案 2 :(得分:-1)

尝试在onCreateView()中为此特定视图(包含任何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;
}