I receive a notice from Leakcanary when debugging my app on a Samsung Galaxy S10 running on Android 12.
Indeed, Leakcanary notifies a leaked activity when toggle from light to night mode or vice versa.
Below is shown the Leakcanary report:
┬───
│ GC Root: System class
│
├─ android.view.inputmethod.InputMethodManager class
│ Leaking: NO (InputMethodManager↓ is not leaking and a class is never
│ leaking)
│ ↓ static InputMethodManager.sInstance
├─ android.view.inputmethod.InputMethodManager instance
│ Leaking: NO (DecorView↓ is not leaking and InputMethodManager is a
│ singleton)
│ ↓ InputMethodManager.mCurRootView
├─ android.view.ViewRootImpl instance
│ Leaking: NO (DecorView↓ is not leaking)
│ mContext instance of com.android.internal.policy.DecorContext, wrapping
│ activity com.my_package.activity.MainActivity
│ with mDestroyed = false
│ ViewRootImpl#mView is not null
│ mWindowAttributes.mTitle = "com.my_package.activity.MainActivity"
│ mWindowAttributes.type = 1
│ ↓ ViewRootImpl.mParentDecorView
├─ com.android.internal.policy.DecorView instance
│ Leaking: NO (View attached)
│ View is part of a window view hierarchy
│ View.mAttachInfo is not null (view attached)
│ View.mWindowAttachCount = 1
│ mContext instance of com.android.internal.policy.DecorContext, wrapping
│ activity com.my_package.activity.MainActivity
│ with mDestroyed = false
│ ↓ DecorView.mMSActions
│ ~~~~~~~~~~
├─ com.samsung.android.multiwindow.MultiSplitActions instance
│ Leaking: UNKNOWN
│ Retaining 43 B in 1 objects
│ ↓ MultiSplitActions.mWindow
│ ~~~~~~~
├─ com.android.internal.policy.PhoneWindow instance
│ Leaking: YES (Window#mDestroyed is true)
│ Retaining 15,0 kB in 286 objects
│ mContext instance of com.my_package.activity.
│ MainActivity with mDestroyed = true
│ mOnWindowDismissedCallback instance of com.my_package.activity.MainActivity with mDestroyed = true
│ ↓ Window.mContext
╰→ com.my_package.activity.MainActivity instance
Leaking: YES (ObjectWatcher was watching this because com.my_package.activity.MainActivity received
Activity#onDestroy() callback and Activity#mDestroyed is true)
Retaining 534,5 kB in 11484 objects
key = 442fa647-742b-4e2f-b4c7-452ea418ffdb
watchDurationMillis = 5868
retainedDurationMillis = 867
dataBackupAgent instance of com.my_package.activity.
MyBackupAgent
mApplication instance of com.my_package.activity.MyApplicationClass
mBase instance of androidx.appcompat.view.ContextThemeWrapper
METADATA
Build.VERSION.SDK_INT: 31
Build.MANUFACTURER: samsung
LeakCanary version: 2.8.1
Stats: LruCache[maxSize=3000,hits=129558,misses=253658,hitRate=33%]
RandomAccess[bytes=21184127,reads=253658,travel=102525154060,range=50140315,size
=69790586]
Analysis duration: 12217 ms
Please do you have any idea concerning the origin of this ?
First of all thank you for your reply.
Indeed, I have a class named MyBackupAgent:
@Singleton
class MyBackupAgent @Inject constructor(
private val backupPrefsKey: String,
private val backupHelper: MyBackupHelper
): BackupAgentHelper() {
override fun onCreate() {
super.onCreate()
addHelper(backupPrefsKey, backupHelper)
}
}
The MyBackupHelper class has the following implementation:
@Singleton
class MyBackupHelper @Inject constructor(
private val context: Context,
private val backupPreferencesKey: String
) : SharedPreferencesBackupHelper(context, backupPreferencesKey) {
.....
}
The MyBackupAgent is injected into Activity with:
@Inject
lateinit var backupAgent: MyBackupAgent
The MyBackupAgent and MyBackupHelper are provided by the MyBaseModule class:
@InstallIn(SingletonComponent::class)
@Module
class MyBaseModule {
@Singleton
@Provides
fun provideMyBackupHelper(@ApplicationContext context: Context, @BackUpPreferencesKey backupPrefsKey: String): MyBackupHelper {
val backupHelper by lazy {
MyBackupHelper(context, backupPrefsKey)
}
return backupHelper
}
@Singleton
@Provides
fun provideMyBackupAgent(@BackUpPreferencesKey backupPreferencesKey: String, backupHelper: MyBackupHelper): MyBackupAgent {
val backupAgent by lazy {
MyBackupAgent(backupPreferencesKey, backupHelper)
}
return backupAgent
}
}