@Override void add(ExcludedRefs.Builder excluded) { if (MOTOROLA.equals(MANUFACTURER) && SDK_INT == KITKAT) { excluded.instanceField("android.app.admin.DevicePolicyManager$SettingsObserver", "this$0") .reason("DevicePolicyManager keeps a reference to the context it has been created with" + " instead of extracting the application context. In this Motorola build," + " DevicePolicyManager has an inner SettingsObserver class that is a content" + " observer, which is held into memory by a binder transport object."); } } },
@Override void add(ExcludedRefs.Builder excluded) { // In Android P, ViewLocationHolder has an mRoot field that is not cleared in its clear() // method. // Introduced in https://github.com/aosp-mirror/platform_frameworks_base/commit/86b326012813f09d8f1de7d6d26c986a909de894 // Bug report: https://issuetracker.google.com/issues/112792715 excluded.instanceField("android.view.ViewGroup$ViewLocationHolder", "mRoot"); } };
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.view.ViewConfiguration", "mContext") .reason("In AOSP the ViewConfiguration class does not have a context." + " Here we have ViewConfiguration.sConfigurations (static field) holding on to a" + " ViewConfiguration instance that has a context that is the activity." + " Observed here: https://github.com/square/leakcanary/issues" + "/1#issuecomment-100324683"); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.content.res.Resources", "mContext") .reason("In AOSP the Resources class does not have a context." + " Here we have ZygoteInit.mResources (static field) holding on to a Resources" + " instance that has a context that is the activity." + " Observed here: https://github.com/square/leakcanary/issues/1#issue-74450184"); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("com.samsung.android.content.clipboard.SemClipboardManager", "mContext") .reason("SemClipboardManager is held in memory by an anonymous inner class" + " implementation of android.os.Binder, thereby leaking an activity context."); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.speech.SpeechRecognizer$InternalListener", "this$0") .reason("Prior to Android 5, SpeechRecognizer.InternalListener was a non static inner" + " class and leaked the SpeechRecognizer which leaked an activity context." + " Fixed in AOSP: https://github.com/android/platform_frameworks_base/commit" + " /b37866db469e81aca534ff6186bdafd44352329b"); } },
@Override void add(ExcludedRefs.Builder excluded) { String reason = "ActivityChooserModel holds a static reference to the last set" + " ActivityChooserModelPolicy which can be an activity context." + " Tracked here: https://code.google.com/p/android/issues/detail?id=172659" + " Hack: https://gist.github.com/andaag/b05ab66ed0f06167d6e0"; excluded.instanceField("android.support.v7.internal.widget.ActivityChooserModel", "mActivityChoserModelPolicy").reason(reason); excluded.instanceField("android.widget.ActivityChooserModel", "mActivityChoserModelPolicy") .reason(reason); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.accounts.AccountManager$AmsTask$Response", "this$1") .reason("AccountManager$AmsTask$Response is a stub and is held in memory by native code," + " probably because the reference to the response in the other process hasn't been" + " cleared." + " AccountManager$AmsTask is holding on to the activity reference to use for" + " launching a new sub- Activity." + " Tracked here: https://code.google.com/p/android/issues/detail?id=173689" + " Fix: Pass a null activity reference to the AccountManager methods and then deal" + " with the returned future to to get the result and correctly start an activity" + " when it's available."); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.os.PersonaManager", "mContext") .reason("android.app.LoadedApk.mResources has a reference to" + " android.content.res.Resources.mPersonaManager which has a reference to" + " android.os.PersonaManager.mContext which is an activity."); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("com.samsung.android.emergencymode.SemEmergencyManager", "mContext") .reason("SemEmergencyManager is a static singleton that leaks a DecorContext." + " Fix: https://gist.github.com/jankovd/a210460b814c04d500eb12025902d60d"); } },
@Override void add(ExcludedRefs.Builder excluded) { String reason = "HUAWEI added a mLastSrvView field to InputMethodManager" + " that leaks a reference to the last served view."; excluded.instanceField("android.view.inputmethod.InputMethodManager", "mLastSrvView") .reason(reason); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.media.MediaScannerConnection", "mContext") .reason("The static method MediaScannerConnection.scanFile() takes an activity context" + " but the service might not disconnect after the activity has been destroyed." + " Tracked here: https://code.google.com/p/android/issues/detail?id=173788" + " Fix: Create an instance of MediaScannerConnection yourself and pass in the" + " application context. Call connect() and disconnect() manually."); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.view.inputmethod.InputMethodManager", "mCurRootView") .reason("The singleton InputMethodManager is holding a reference to mCurRootView long" + " after the activity has been destroyed." + " Observed on ICS MR1: https://github.com/square/leakcanary/issues/1" + "#issuecomment-100579429" + " Hack: https://gist.github.com/pyricau/4df64341cc978a7de414"); } },
@Override void add(ExcludedRefs.Builder excluded) { // DisplayEventReceiver keeps a reference message queue object so that it is not GC'd while // the native peer of the receiver is using them. // The main thread message queue is held on by the main Looper, but that might be a longer // path. Let's not confuse people with a shorter path that is less meaningful. excluded.instanceField("android.view.Choreographer$FrameDisplayEventReceiver", "mMessageQueue").alwaysExclude(); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("com.lge.systemservice.core.LGContext", "mContext") .reason("LGContext is a static singleton that leaks an activity context."); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.sec.clipboard.ClipboardUIManager", "mContext") .reason("ClipboardUIManager is a static singleton that leaks an activity context." + " Fix: trigger a call to ClipboardUIManager.getInstance() in Application.onCreate()" + " , so that the ClipboardUIManager instance gets cached with a reference to the" + " application context. Example: https://gist.github.com/cypressious/" + "91c4fb1455470d803a602838dfcd5774"); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.app.ActivityThread$ActivityClientRecord", "nextIdle") .reason("Android AOSP sometimes keeps a reference to a destroyed activity as a" + " nextIdle client record in the android.app.ActivityThread.mActivities map." + " Not sure what's going on there, input welcome."); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.media.AudioManager$1", "this$0") .reason("Prior to Android M, VideoView required audio focus from AudioManager and" + " never abandoned it, which leaks the Activity context through the AudioManager." + " The root of the problem is that AudioManager uses whichever" + " context it receives, which in the case of the VideoView example is an Activity," + " even though it only needs the application's context. The issue is fixed in" + " Android M, and the AudioManager now uses the application's context." + " Tracked here: https://code.google.com/p/android/issues/detail?id=152173" + " Fix: https://gist.github.com/jankovd/891d96f476f7a9ce24e2"); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.appwidget.AppWidgetHost$Callbacks", "this$0") .reason("android.appwidget.AppWidgetHost$Callbacks is a stub and is held in memory native" + " code. The reference to the `mContext` was not being cleared, which caused the" + " Callbacks instance to retain this reference" + " Fixed in AOSP: https://github.com/android/platform_frameworks_base/commit" + "/7a96f3c917e0001ee739b65da37b2fadec7d7765"); } },
@Override void add(ExcludedRefs.Builder excluded) { excluded.instanceField("android.widget.SpellChecker$1", "this$0") .reason("SpellChecker holds on to a detached view that points to a destroyed activity." + " mSpellRunnable is being enqueued, and that callback should be removed when " + " closeSession() is called. Maybe closeSession() wasn't called, or maybe it was " + " called after the view was detached."); } },