【发布时间】:2023-07-11 16:51:01
【问题描述】:
通过Executor类发起网络通信时,我使用了showProgress函数。通信结束后收到结果时,使用 hideProgess 函数。代码如下,我在BaseActivity中使用。
private val networkIO = Executors.newFixedThreadPool(3)
private var progressBar: AlertDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
progressBar = AlertDialog.Builder(this)
.setView(R.layout.dialog_loading)
.setCancelable(false)
.create()
.apply { window?.setBackgroundDrawableResource(android.R.color.transparent) }
doOnCreate()
}
override fun onDestroy() {
progressBar = null
super.onDestroy()
}
fun showProgress() {
runOnUiThread {
try {
if (progressBar?.isShowing == false) {
progressBar?.show()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
fun hideProgress() {
runOnUiThread { progressBar?.dismiss() }
}
在 MainActivity 中执行下一次网络通信后移动到另一个 Activity 时发生内存泄漏。
private fun fetchCard() {
networkIO.execute {
showProgress()
networkManager.getCardInfo { _, code, message ->
Timber.d("## $code")
Timber.d("## $message")
hideProgress()
}
}
}
LeakCanary 提供的泄漏原因
2021-03-08 05:11:42.552 8678-8678/com.tagless D/LeakCanary:
┬───
│ GC Root: System class
│
├─ android.app.ActivityThread class
│ Leaking: NO (MainActivity↓ is not leaking and a class is never leaking)
│ ↓ static ActivityThread.sCurrentActivityThread
├─ android.app.ActivityThread instance
│ Leaking: NO (MainActivity↓ is not leaking)
│ mInitialApplication instance of com.tagless.TaglessApp
│ mSystemContext instance of android.app.ContextImpl
│ mSystemUiContext instance of android.app.ContextImpl
│ ↓ ActivityThread.mActivities
├─ android.util.ArrayMap instance
│ Leaking: NO (MainActivity↓ is not leaking)
│ ↓ ArrayMap.mArray
├─ java.lang.Object[] array
│ Leaking: NO (MainActivity↓ is not leaking)
│ ↓ Object[].[3]
├─ android.app.ActivityThread$ActivityClientRecord instance
│ Leaking: NO (MainActivity↓ is not leaking)
│ activity instance of com.tagless.ui.main.MainActivity with mDestroyed = false
│ ↓ ActivityThread$ActivityClientRecord.activity
├─ com.tagless.ui.main.MainActivity instance
│ Leaking: NO (Activity#mDestroyed is false)
│ mApplication instance of com.tagless.TaglessApp
│ mBase instance of androidx.appcompat.view.ContextThemeWrapper
│ ↓ BaseActivity.progressBar
│ ~~~~~~~~~~~
├─ androidx.appcompat.app.AlertDialog instance
│ Leaking: UNKNOWN
│ Retaining 106.7 kB in 1647 objects
│ mContext instance of android.view.ContextThemeWrapper, wrapping activity com.tagless.ui.main.MainActivity with
│ mDestroyed = false
│ Dialog#mDecor is null
│ ↓ Dialog.mWindow
│ ~~~~~~~
├─ com.android.internal.policy.PhoneWindow instance
│ Leaking: UNKNOWN
│ Retaining 23.3 kB in 289 objects
│ mContext instance of android.view.ContextThemeWrapper, wrapping activity com.tagless.ui.main.MainActivity with
│ mDestroyed = false
│ Window#mDestroyed is false
│ ↓ PhoneWindow.mDecor
│ ~~~~~~
╰→ com.android.internal.policy.DecorView instance
Leaking: YES (ObjectWatcher was watching this because com.android.internal.policy.DecorView received
View#onDetachedFromWindow() callback)
Retaining 3.4 kB in 59 objects
key = 5f2f819a-9640-429f-afff-4489f7b039d2
watchDurationMillis = 5703
retainedDurationMillis = 702
View not part of a window view hierarchy
View.mAttachInfo is null (view detached)
View.mWindowAttachCount = 1
mContext instance of android.view.ContextThemeWrapper, wrapping activity com.tagless.ui.main.MainActivity with
mDestroyed = false
METADATA
Build.VERSION.SDK_INT: 29
Build.MANUFACTURER: samsung
LeakCanary version: 2.6
App process name: com.tagless
Stats: LruCache[maxSize=3000,hits=5668,misses=70891,hitRate=7%]
RandomAccess[bytes=3887192,reads=70891,travel=27244024610,range=20775300,size=25990100]
Heap dump reason: user request
Analysis duration: 3864 ms
提前谢谢任何人请帮忙!
【问题讨论】:
-
你试过用 .dispose() 或 .cancel() 代替 .dismiss() 吗?
-
@javdromero 我尝试了取消功能,但它是相同的,并且 dispose 不是对话框功能。
标签: android memory-leaks leakcanary