简体   繁体   中英

Handler()postDelay is unreachable for this Kotlin code, how to fix it?

I have a function, where I just explicitly want to delay the return value

private fun loadData(): DataModel? {
    Handler(Looper.getMainLooper()).postDelayed(
    when (fetchStyle) {
        FetchStyle.FETCH_SUCCESS -> return DataModel("Data Loaded")
        FetchStyle.FETCH_EMPTY -> return DataModel("")
        FetchStyle.FETCH_ERROR -> throw IllegalStateException("Error Fetching")
    }, 3000)
}

However there's a warning state that postDelayed is unreachable, hence the 3s delay is not triggered.

To make it reachable, I have to add the extra parenthesis around

private fun loadData(): DataModel? {
    Handler(Looper.getMainLooper()).postDelayed({
    when (fetchStyle) {
        FetchStyle.FETCH_SUCCESS -> DataModel("Data Loaded")
        FetchStyle.FETCH_EMPTY -> DataModel("")
        FetchStyle.FETCH_ERROR -> throw IllegalStateException("Error Fetching")
    }}, 3000)
}

But then, I can't return the DataModel value anymore. How could I fix this to have the delay of 3s, while I could still return the respective DataModel or throw the exception?

If you just want to block the current thread, you can use Thread.sleep :

private fun loadData(): DataModel? {
    Thread.sleep(3000);
    return when (fetchStyle) {
        FetchStyle.FETCH_SUCCESS -> DataModel("Data Loaded")
        FetchStyle.FETCH_EMPTY -> DataModel("")
        FetchStyle.FETCH_ERROR -> throw IllegalStateException("Error Fetching")
    }
}

An example for using Handler and Runnable instead, with a separate callback function:

private fun loadData(): DataModel? {
    Handler(Looper.getMainLooper()).postDelayed({
        val result = when (fetchStyle) {
            FetchStyle.FETCH_SUCCESS -> DataModel("Data Loaded")
            FetchStyle.FETCH_EMPTY -> DataModel("")
            FetchStyle.FETCH_ERROR -> throw IllegalStateException("Error Fetching")
        }
        loadDataCallback(result)
    }, 3000)
}

fun useLoadData() {
    loadData()
}

private fun loadDataCallback(dataModel: DataModel?) {
    // use result here
}

A more Kotlin-like approach, passing a function as the callback:

private fun loadData(callback: (DataModel?) -> Unit): DataModel? {
    Handler(Looper.getMainLooper()).postDelayed({
        val result = when (fetchStyle) {
            FetchStyle.FETCH_SUCCESS -> DataModel("Data Loaded")
            FetchStyle.FETCH_EMPTY -> DataModel("")
            FetchStyle.FETCH_ERROR -> throw IllegalStateException("Error Fetching")
        }
        callback(result)
    }, 3000)
}

fun useLoadData() {
    loadData { dataModel ->
        // use result here
    }
}

Note that these examples don't block any threads, and the Handler(Looper.getMainLooper()) part of your original example code (that I kept for these examples) will place the execution of the when statement as well as the callbacks after that back on the main thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM