android - 这个 Runnable 类会导致内存泄漏吗?
问题描述
我创建了一个类并用Runnable
. 这个类应该在后台进行操作并在 UI 线程上发布结果。但是,我使用这个Runnable
类的变量属于外部类(父类)。例子:
Class MainFragment {
onStart() {
val runnable = BackgroundRunnable()
Thread(runnable).start()
}
private inner class BackgroundRunnable: Runnable {
onRun() {
//using MainFragment`s member variables here
//performing background ops that can take more than 48ms
}
getActivity().runOnUiThread(object : Runnable {
override fun run() {
//notfiyDataSetChanged()
}
}
}
}
从上面的示例代码中可以看出,我使用inner
的是访问MainFragment
类成员变量。这会导致内存泄漏吗?如果是怎么避免呢?
这是我写的实际代码:
private inner class BackgroundRunnable : Runnable {
override fun run() {
list!!.clear()
listItems!!.clear()
list = dbHandler!!.readAllNotes()
for (noteReader in list!!.iterator()) {
val note = UserNotes()
note.noteTitle = noteReader.noteTitle
note.noteText = noteReader.noteText
note.noteID = noteReader.noteID
note.noteColor = noteReader.noteColor
note.noteEncrypted = noteReader.noteEncrypted
note.noteCheckList = noteReader.noteCheckList
note.noteDate = noteReader.noteDate
note.noteTempDel = noteReader.noteTempDel
note.noteArchived = noteReader.noteArchived
note.noteReminderID = noteReader.noteReminderID
note.noteReminderText = noteReader.noteReminderText
listItems!!.add(note)
}
activity!!.runOnUiThread(object : Runnable {
override fun run() {
adapter!!.notifyDataSetChanged()
return
}
})
}
}
使用弱引用
private class BackgroundRunnable internal constructor(context: NotesFrag) : Runnable {
private val weakReference = WeakReference(context)
override fun run() {
val parentClass = weakReference.get()
parentClass!!.list!!.clear()
parentClass.listItems!!.clear()
parentClass.list = parentClass.dbHandler!!.readAllNotes()
for (noteReader in parentClass.list!!.iterator()) {
val note = UserNotes()
note.noteTitle = noteReader.noteTitle
note.noteText = noteReader.noteText
note.noteID = noteReader.noteID
note.noteColor = noteReader.noteColor
note.noteEncrypted = noteReader.noteEncrypted
note.noteCheckList = noteReader.noteCheckList
note.noteDate = noteReader.noteDate
note.noteTempDel = noteReader.noteTempDel
note.noteArchived = noteReader.noteArchived
note.noteReminderID = noteReader.noteReminderID
note.noteReminderText = noteReader.noteReminderText
parentClass.listItems!!.add(note)
}
parentClass.activity!!.runOnUiThread(object : Runnable {
override fun run() {
parentClass.adapter!!.notifyDataSetChanged()
return
}
})
}
}
解决方案
如果非静态内部类比容器对象寿命长,它们可能会泄漏内存。在您的情况下,Fragment
在完成之前不会进行 GC,Runnable
因为内部类持有对包含的隐式引用Fragment
。
为了解决这个问题,如果您直接WeakReference
访问WeakReference
Activity/Fragment(就像您getActivity()
在Runnable
)。
推荐阅读
- python - Python jupyter库导入错误
- python - 编辑表单中另一个模型的 Django Admin 过滤器
- python - 按值将文件中的数字附加到列表中
- java - 在 Apahce commons VFS 中连接不同的域
- javascript - Is express() function used in expressJS, a global function?
- javascript - 奇怪的javascript数组推送行为
- java - Karaf 在 feature:repo-add 上省略了本地 maven 存储库
- ruby - Appium 驱动操作系统名称
- mysql - 有外键时插入一行
- javascript - 有两个全宽 HTML 元素重叠但都是交互的