kotlin 内存泄漏Android

6bc51xsx  于 2023-02-05  发布在  Kotlin
关注(0)|答案(1)|浏览(260)

你们有什么建议是什么可以导致这个内存泄漏,我从泄漏金丝雀?下面是我从报告中得到的描述。
步骤重现是,在设置菜单中,点击开关,将执行主题更改,此操作后,泄漏发生。下面我将提供从SettingsFragmentClass的代码块。任何帮助将是最受欢迎的家伙。
基本上,调用此行时会发生问题。AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)

┬───
│ GC Root: Global variable in native code
│
├─ android.graphics.animation.RenderNodeAnimator instance
│    Leaking: UNKNOWN
│    Retaining 1.1 MB in 16344 objects
│    ↓ RenderNodeAnimator.mTarget
│                         ~~~~~~~
├─ android.graphics.RenderNode instance
│    Leaking: UNKNOWN
│    Retaining 1.1 MB in 16274 objects
│    ↓ RenderNode.mHostView
│                 ~~~~~~~~~
├─ com.google.android.material.switchmaterial.SwitchMaterial instance
│    Leaking: YES (View.mContext references a destroyed activity)
│    Retaining 1.1 MB in 16272 objects
│    View not part of a window view hierarchy
│    View.mAttachInfo is null (view detached)
│    View.mID = R.id.null
│    View.mWindowAttachCount = 1
│    mContext instance of com.flixeron.my_passkeeper.main.MainActivity with
│    mDestroyed = true
│    ↓ View.mContext
╰→ com.flixeron.my_passkeeper.main.MainActivity instance
​     Leaking: YES (ObjectWatcher was watching this because com.flixeron.
​     my_passkeeper.main.MainActivity received Activity#onDestroy() callback
​     and Activity#mDestroyed is true)
​     Retaining 251.2 kB in 5956 objects
​     key = 3c074833-b927-4971-b2b5-0a77b9e68bde
​     watchDurationMillis = 5216
​     retainedDurationMillis = 215
​     mApplication instance of com.flixeron.my_passkeeper.main.MainApplication
​     mBase instance of androidx.appcompat.view.ContextThemeWrapper
METADATA
Build.VERSION.SDK_INT: 31
Build.MANUFACTURER: Xiaomi
LeakCanary version: 2.7
App process name: com.flixeron.my_passkeeper
Stats: LruCache[maxSize=3000,hits=6345,misses=185335,hitRate=3%]
RandomAccess[bytes=9694284,reads=185335,travel=115234430872,range=38720254,size=
46574102]
Heap dump reason: 7 retained objects, app is visible
Analysis duration: 15049 ms

片段分类

class SettingsFragment : Fragment() {

private val cardViewModel: CardViewModel by viewModel()

private var bindingProp: FragmentSettingsBinding? = null
private val binding get() = bindingProp!!

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    bindingProp = FragmentSettingsBinding.inflate(inflater, container, false)

    setTextLockTime()
    configureScreenShoots()
    themeSettings()

    // changing dark/light mode
    binding.switchTheme.setOnClickListener {
        if (!PreferenceProvider.darkMode) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
            PreferenceProvider.darkMode = true
            binding.imageViewTheme.setImageResource(R.drawable.ic_dark_mode)
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            PreferenceProvider.darkMode = false
            binding.imageViewTheme.setImageResource(R.drawable.ic_light_mode)
        }
    }

override fun onDestroyView() {
    super.onDestroyView()
    bindingProp = null
  }
}

Xml文件

<androidx.constraintlayout.widget.ConstraintLayout
                    android:id="@+id/switchTheme"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="30dp"
                    app:layout_constraintBottom_toBottomOf="@+id/textViewChangeTheme"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintTop_toTopOf="@+id/textViewChangeTheme">

                    <com.google.android.material.switchmaterial.SwitchMaterial
                        android:id="@+id/switchTheme1"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:clickable="false"
                        android:focusable="false"
                        app:layout_constraintBottom_toBottomOf="@+id/switchTheme"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintTop_toTopOf="@+id/switchTheme"
                        android:scaleX="1.3"
                        android:scaleY="1.3"/>

                </androidx.constraintlayout.widget.ConstraintLayout>

更新泄漏金丝雀

┬───
│ 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.flixeron.my_passkeeper.main.MainActivity with mDestroyed =
│    false
│    ViewRootImpl#mView is not null
│    mWindowAttributes.mTitle = "com.flixeron.my_passkeeper/com.flixeron.
│    my_passkeeper.main.MainActivity"
│    mWindowAttributes.type = 1
│    ↓ ViewRootImpl.mView
├─ 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.flixeron.my_passkeeper.main.MainActivity with mDestroyed =
│    false
│    ↓ View.mResources
│           ~~~~~~~~~~
├─ dev.b3nedikt.app_locale.AppLocaleResources instance
│    Leaking: UNKNOWN
│    Retaining 1.9 kB in 55 objects
│    context instance of androidx.appcompat.view.ContextThemeWrapper
│    ↓ AppLocaleResources.context
│                         ~~~~~~~
├─ androidx.appcompat.view.ContextThemeWrapper instance
│    Leaking: UNKNOWN
│    Retaining 274.9 kB in 6390 objects
│    mBase instance of io.github.inflationx.viewpump.ViewPumpContextWrapper
│    ContextThemeWrapper does not wrap a known Android context
│    ↓ ContextWrapper.mBase
│                     ~~~~~
├─ io.github.inflationx.viewpump.ViewPumpContextWrapper instance
│    Leaking: UNKNOWN
│    Retaining 270.3 kB in 6242 objects
│    mBase instance of dev.b3nedikt.app_locale.AppLocaleContextWrapper
│    ViewPumpContextWrapper does not wrap a known Android context
│    ↓ ContextWrapper.mBase
│                     ~~~~~
├─ dev.b3nedikt.app_locale.AppLocaleContextWrapper instance
│    Leaking: UNKNOWN
│    Retaining 270.2 kB in 6236 objects
│    mBase instance of android.app.ContextImpl
│    AppLocaleContextWrapper does not wrap a known Android context
│    ↓ ContextWrapper.mBase
│                     ~~~~~
├─ android.app.ContextImpl instance
│    Leaking: YES (ContextImpl.mOuterContext is an instance of com.flixeron.
│    my_passkeeper.main.MainActivity with Activity.mDestroyed true)
│    Retaining 268.1 kB in 6175 objects
│    mAutofillClient instance of com.flixeron.my_passkeeper.main.MainActivity
│    with mDestroyed = true
│    mOuterContext instance of com.flixeron.my_passkeeper.main.MainActivity
│    with mDestroyed = true
│    ↓ ContextImpl.mAutofillClient
╰→ com.flixeron.my_passkeeper.main.MainActivity instance
​     Leaking: YES (ObjectWatcher was watching this because com.flixeron.
​     my_passkeeper.main.MainActivity received Activity#onDestroy() callback
​     and Activity#mDestroyed is true)
​     Retaining 264.2 kB in 6091 objects
​     key = 44a30066-31c8-4abb-8660-907035d18457
​     watchDurationMillis = 5229
​     retainedDurationMillis = 224
​     mApplication instance of com.flixeron.my_passkeeper.main.MainApplication
​     mBase instance of androidx.appcompat.view.ContextThemeWrapper
METADATA
Build.VERSION.SDK_INT: 31
Build.MANUFACTURER: Xiaomi
LeakCanary version: 2.7
App process name: com.flixeron.my_passkeeper
Count of retained yet cleared: 1 KeyedWeakReference instances
Stats: LruCache[maxSize=3000,hits=3959,misses=160418,hitRate=2%]
RandomAccess[bytes=8403631,reads=160418,travel=86543130456,range=36387679,size=4
4147138]
Heap dump reason: 6 retained objects, app is visible
Analysis duration: 11869 ms```
u3r8eeie

u3r8eeie1#

您的泄漏是严格相关的图形用户界面,这是得到restared当用户改变主题与您的选择
Fragment被销毁时,考虑通过释放绑定的View来释放GUI相关对象(并且将进一步/很快使用新主题重新创建)

override fun onDestroyView() {
    bindingProp = null
    super.onDestroyView()
}

相关问题