【发布时间】:2020-09-14 15:21:03
【问题描述】:
刚开始通过 Leak Canary 了解内存泄漏,如果我混淆或误解任何内容,请原谅我。 Leak canary 告诉我存在内存泄漏,我已将其范围缩小到这一行
NavigationUI.setupActionBarWithNavController(
it,
navController
)
导航控制器被调用并设置为这样的变量
val navController = findNavController(this@PokemonDetailFragment)
'it' 是我的活动转换为应用兼容活动,完整的 sn-p 看起来像这样:
mainActivity = (activity as AppCompatActivity)
mainActivity?.let {
it.setSupportActionBar(toolbar)
val navController = findNavController(this@PokemonDetailFragment)
NavigationUI.setupActionBarWithNavController(
it,
navController
)
}
我尝试了三件事,1. 改为注入活动,2. 将活动设置为全局可为空的变量并在 onDestroyView 中将其设置为空,以及 3. 尝试使用 NavigationUI.setupWithNavController 而不是 setupActionBarWithNavController 需要工具栏和导航控制器
NavigationUI.setupWithNavController(
binding.toolbar,
findNavController(this@PokemonDetailFragment)
)
但这些都不能解决问题。
删除第一个代码块肯定会消除泄漏,但是 Leak Canary 并未将泄漏显示为与第三方库有关,并且确实说它是我下面代码中的一个变量是堆转储
```
┬───
│ GC Root: Local variable in native code
│
├─ android.os.HandlerThread instance
│ Leaking: NO (PathClassLoader↓ is not leaking)
│ Thread name: 'LeakCanary-Heap-Dump'
│ ↓ HandlerThread.contextClassLoader
├─ dalvik.system.PathClassLoader instance
│ Leaking: NO (InternalLeakCanary↓ is not leaking and A ClassLoader is never leaking)
│ ↓ PathClassLoader.runtimeInternalObjects
├─ java.lang.Object[] array
│ Leaking: NO (InternalLeakCanary↓ is not leaking)
│ ↓ Object[].[502]
├─ leakcanary.internal.InternalLeakCanary class
│ Leaking: NO (MainActivity↓ is not leaking and a class is never leaking)
│ ↓ static InternalLeakCanary.resumedActivity
├─ com.sealstudios.pokemonApp.MainActivity instance
│ Leaking: NO (FragmentContainerView↓ is not leaking and Activity#mDestroyed is false)
│ ↓ MainActivity._binding
├─ com.sealstudios.pokemonApp.databinding.ActivityMainBinding instance
│ Leaking: NO (FragmentContainerView↓ is not leaking)
│ ↓ ActivityMainBinding.navHostFragment
├─ androidx.fragment.app.FragmentContainerView instance
│ Leaking: NO (View attached)
│ mContext instance of com.sealstudios.pokemonApp.MainActivity with mDestroyed = false
│ View.parent androidx.constraintlayout.widget.ConstraintLayout attached as well
│ View#mParent is set
│ View#mAttachInfo is not null (view attached)
│ View.mID = R.id.nav_host_fragment
│ View.mWindowAttachCount = 1
│ ↓ FragmentContainerView.mKeyedTags
│ ~~~~~~~~~~
├─ android.util.SparseArray instance
│ Leaking: UNKNOWN
│ ↓ SparseArray.mValues
│ ~~~~~~~
├─ java.lang.Object[] array
│ Leaking: UNKNOWN
│ ↓ Object[].[0]
│ ~~~
├─ androidx.navigation.NavHostController instance
│ Leaking: UNKNOWN
│ ↓ NavHostController.mOnDestinationChangedListeners
│ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
├─ java.util.concurrent.CopyOnWriteArrayList instance
│ Leaking: UNKNOWN
│ ↓ CopyOnWriteArrayList.array
│ ~~~~~
├─ java.lang.Object[] array
│ Leaking: UNKNOWN
│ ↓ Object[].[1]
│ ~~~
├─ androidx.navigation.ui.ActionBarOnDestinationChangedListener instance
│ Leaking: UNKNOWN
│ ↓ ActionBarOnDestinationChangedListener.mContext
│ ~~~~~~~~
├─ android.view.ContextThemeWrapper instance
│ Leaking: UNKNOWN
│ ContextThemeWrapper wraps an Activity with Activity.mDestroyed false
│ ↓ ContextThemeWrapper.mBase
│ ~~~~~
├─ dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper instance
│ Leaking: UNKNOWN
│ ViewComponentManager$FragmentContextWrapper wraps an Activity with Activity.mDestroyed false
│ ↓ ViewComponentManager$FragmentContextWrapper.fragment
│ ~~~~~~~~
╰→ com.sealstudios.pokemonApp.ui.PokemonDetailFragment instance
Leaking: YES (ObjectWatcher was watching this because com.sealstudios.pokemonApp.ui.PokemonDetailFragment received Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
key = 724affdf-d1ac-47ff-82b8-6907ced5b666
watchDurationMillis = 9052
retainedDurationMillis = 4051
METADATA
Build.VERSION.SDK_INT: 29
Build.MANUFACTURER: Google
LeakCanary version: 2.4
App process name: com.sealstudios.pokemonApp
Analysis duration: 14474 ms```
感谢任何帮助我只想设置需要 AppCompatActivity 的工具栏,然后正确处理它或允许系统执行它
我正在使用 Hilt 并发现这不确定它是否相关,尽管我的堆确实提到了 ContextThemeWrapper - https://github.com/google/dagger/issues/2070
【问题讨论】:
-
能否提供 findNavController 和 NavigationUI.setupActionBarWithNavController 中的代码?
-
@D.Pereira 这些是导航架构组件方法
-
日志似乎表明 PokemonDetailFragment 已被破坏,但仍在某处被引用。我的想法是 findNavController 返回的控制器持有这个引用
标签: android memory-leaks navigation leakcanary appcompatactivity