如何在做某事之前正确等待 HandlerThread 启动?
How to properly wait for HandlerThread to start before doing something?
在我的项目中,有时创建的线程没有像应该的那样快速启动,这种情况发生在极少数情况下,但大多数情况下会发生在 slow/older 手机上。
我的线程喜欢..
class DBThread(threadName: String) : HandlerThread(threadName) {
private var mWorkerHandler: Handler? = null
override fun onLooperPrepared() {
super.onLooperPrepared()
mWorkerHandler = Handler(looper)
}
fun createTask(task: Runnable) {
mWorkerHandler?.post(task)
}
}
当我使用它并调用 activity..
//this will handle db queries on background and not on main ui thread
var mDbThread: DBThread = DBThread("dbThread")
//use this to interact to main ui thread from different thread
val mUiHandler = Handler()
var mDb: LocalDatabase? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDbThread.start()
mDb = LocalDatabase.getInstance(this)
fetchAndSetList()
}
override fun onDestroy() {
super.onDestroy()
LocalDatabase.destroyInstance()
mDbThread.quitSafely()
}
private fun fetchAndSetList(){
mDbThread.createTask(Runnable {
val list = getList()
mUiHandler.post {
// this sometimes does not trigger
setList(list)
}
})
}
setList 函数有时不会触发。
所以我做了这样的事情。
fun createTask(task: Runnable) {
if(mWorkerHandler == null ){
createTask(task)
return
}
mWorkerHandler?.post(task)
}
修改后的操作似乎有效,但我不太确定这样做是否安全。提前谢谢你。
我认为mWorkerhandler 为null 的原因是因为Thread.start 将创建新的VMThread 并在VMThread 中启动looper。整个流程是异步的,所以当实际调用 onLooperPrepared 时,为时已晚,因为 "fetchAndSetList" 已经在尝试使用 mWorkerHandler
解决方案是在 HandlerThread 之外创建处理程序:
Handler workerHandler;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDbThread.start()
workerHandler = new Handler(mDbThread.getLooper());
mDb = LocalDatabase.getInstance(this)
fetchAndSetList()
}
private fun fetchAndSetList(){
workerHandler.post(Runnable {
val list = getList()
mUiHandler.post {
// this sometimes does not trigger
setList(list)
}
})
}
在我的项目中,有时创建的线程没有像应该的那样快速启动,这种情况发生在极少数情况下,但大多数情况下会发生在 slow/older 手机上。
我的线程喜欢..
class DBThread(threadName: String) : HandlerThread(threadName) {
private var mWorkerHandler: Handler? = null
override fun onLooperPrepared() {
super.onLooperPrepared()
mWorkerHandler = Handler(looper)
}
fun createTask(task: Runnable) {
mWorkerHandler?.post(task)
}
}
当我使用它并调用 activity..
//this will handle db queries on background and not on main ui thread
var mDbThread: DBThread = DBThread("dbThread")
//use this to interact to main ui thread from different thread
val mUiHandler = Handler()
var mDb: LocalDatabase? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDbThread.start()
mDb = LocalDatabase.getInstance(this)
fetchAndSetList()
}
override fun onDestroy() {
super.onDestroy()
LocalDatabase.destroyInstance()
mDbThread.quitSafely()
}
private fun fetchAndSetList(){
mDbThread.createTask(Runnable {
val list = getList()
mUiHandler.post {
// this sometimes does not trigger
setList(list)
}
})
}
setList 函数有时不会触发。 所以我做了这样的事情。
fun createTask(task: Runnable) {
if(mWorkerHandler == null ){
createTask(task)
return
}
mWorkerHandler?.post(task)
}
修改后的操作似乎有效,但我不太确定这样做是否安全。提前谢谢你。
我认为mWorkerhandler 为null 的原因是因为Thread.start 将创建新的VMThread 并在VMThread 中启动looper。整个流程是异步的,所以当实际调用 onLooperPrepared 时,为时已晚,因为 "fetchAndSetList" 已经在尝试使用 mWorkerHandler
解决方案是在 HandlerThread 之外创建处理程序:
Handler workerHandler;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDbThread.start()
workerHandler = new Handler(mDbThread.getLooper());
mDb = LocalDatabase.getInstance(this)
fetchAndSetList()
}
private fun fetchAndSetList(){
workerHandler.post(Runnable {
val list = getList()
mUiHandler.post {
// this sometimes does not trigger
setList(list)
}
})
}