我创建了一个类,并使用Runnable
对其进行了扩展。该类应该在后台执行操作并将结果发布到UI线程上。但是,我正在使用此Runnable
类的变量属于outter类(Parent类)。示例:
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
}
})
}
}
答案 0 :(得分:1)
如果非静态内部类的寿命超过了容器对象,则它们可能会泄漏内存。
在您的情况下,Fragment
在完成Runnable
之前不会得到GC,因为内部类持有对包含的Fragment
的隐式引用。
要解决此问题,通常建议坚持使用WeakReference
对象,从中需要包含类的数据,或者坚持使用WeakReference
到活动/片段(如果您是)直接访问活动/片段(就像您在getActivity()
中使用Runnable
一样)。
答案 1 :(得分:0)
您的代码似乎没有泄漏内存。但是,确保它的最佳方法是对其进行测试。运行它多次,然后查看内存是否增加。有什么理由让您认为这是泄漏吗?
换句话说,您可能应该避免拆开所有内容并保留可选内容(这意味着使用?
而非!!
)。