Как правильно ждать запуска 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)
        }
   })
}
Другие вопросы по тегам