Kotlin alternative for Handler

Viewed 194

Lets talk about a specific example, consider :

abstract class AsyncWriter {
    private val handler : Handler
    init {
        val handlerThread = HandlerThread("AsyncWriter")
        handlerThread.start()
        handler = Handler(handlerThread.looper)
    }

    protected abstract fun internalWrite(s: String);
    protected abstract fun internalClose()

    fun write(s: String) {
        handler.post {
            internalWrite(s)
        }
    }

    fun close() {
        handler.post {
            internalClose()
        }
    }
    
}

With Handler, since its managing a single thread job queue i can be sure that when the resource is closed, all previously requested writes were written and only then the resource was closed.

Attempting to easily migrate to Kotlin's coroutines :

abstract class AsyncWriter {

    protected abstract fun internalWrite(s: String);
    protected abstract fun internalClose()

    fun write(s: String) {
        GlobalScope.launch {
            internalWrite(s)
        }
    }

    fun close() {
        GlobalScope.launch {
            internalClose()
        }
    }

}

Is quite nice but no longer guarantees resource will close after all previous writes.(1. right?)

There may be some work arounds like :

abstract class AsyncWriter {

    protected abstract fun internalWrite(s: String);
    protected abstract fun internalClose()
    private val d = Executors.newSingleThreadExecutor().asCoroutineDispatcher()

    fun write(s: String) {
        GlobalScope.launch(d) {
            internalWrite(s)
        }
    }

    fun close() {
        GlobalScope.launch(d) {
            internalClose()
        }
    }

}

Which im not even sure that will work (2. it wont work right? i think it wont since continuations of all prev non finished writes and the close execution will be in some kind of a race condition)

or this approach which will work i think but will make synchronization overhead over the simple handler approach (3. right?) :

abstract class AsyncWriter {

    protected abstract fun internalWrite(s: String);
    protected abstract fun internalClose()
    private val m = Mutex()

    fun write(s: String) {
        GlobalScope.launch {
            m.withLock {
                internalWrite(s)
            }
        }
    }

    fun close() {
        GlobalScope.launch {
            m.withLock {
                internalClose()
            }
        }
    }

}
  1. What is the prefered kotlin tool to migrate from using a handler for this use case? or is handler still the best way to do that?

Thanks!

NOTE: I numbered the questions along the way for easy reference

0 Answers
Related