Как правильно ждать запуска HandlerThread, прежде чем что-то делать?
В Моем проекте иногда созданный поток запускается не так быстро, как следовало бы. Это происходит в минимальных случаях, но в основном это происходит на медленных / старых телефонах.
Мне моя нить нравится..
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)
}
}
и когда я использую его и призываю к активности..
//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)
}
модифицированное действие, кажется, работает, но я не совсем уверен, является ли это БЕЗОПАСНЫМ способом сделать это. Заранее спасибо.
1 ответ
Я думаю, что причина, по которой mWorkerhandler равен null, заключается в том, что Thread.start создаст новый VMThread и запустит петлитель в VMThread. Весь поток является асинхронным, поэтому, когда фактически вызывается 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)
}
})
}