5

We have Activities and Fragments leaking and have traced the cause back to what appears to be un-removed ChangeWatchers on TextViews.

Scenario: Activity A starts Activity B. B has a textPassword EditText field in its layout. Activity B finishes.

The HPROF dump shows that there is still one instance of Activity B. Its gcroot path is the following:

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 

This also happens if you Linkify.addLinks to a TextView.

Is there any way to clean up Activity B?

Daddyboy
  • 1,412
  • 13
  • 19

3 Answers3

1

As far as I can tell, this appears to be a bug in Android related to the TextView ChangeWatcher and Linkify or Html.fromHtml spannable strings. I was able to work around the problem by calling setText(null) in my activity's onDestroy(). There may be other workarounds that work as well, but I wasn't able to find any further information on the leak.

emmby
  • 99,783
  • 65
  • 191
  • 249
  • 1
    I tried that, I cant seem to find anything to fix it been at it for days. see my post as well http://stackoverflow.com/questions/18348049/android-edittext-memory-leak – MobDev Aug 21 '13 at 04:03
0

For us, the problem was caused by a PasswordTransformationMethod in the EditText. Specifically for us, it is wrapped in a TextInputLayout, so we have to toggle it there like so (this code is in a Fragment#onDestroyView()):

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

Happening in androidx.appcompat:appcompat:1.0.0

Xavier Rubio Jansana
  • 6,388
  • 1
  • 27
  • 50
-1

Try to use Application Context instead of Activity Context in onCreateView() for this particular View (which contain any android:textIsSelectable="true" components).

// 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;
}