How to use Handler and handleMessage in Kotlin?
Asked Answered
C

3

19

Java code:

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
       // code here
    }
};

How to convert this java code to Kotlin?

I tried this:

private val mHandler = object : Handler() {
    fun handleMessage(msg: Message) {
       // code here
    }
}

But this is seems to be incorrect and gives a compile time error on object

Cindiecindra answered 26/8, 2018 at 10:10 Comment(0)
P
19

Problem: The syntax to override handleMessage() method of the Handler class is incorrect.

Solution: Add override keyword before the function that you want to override.

private val mHandler = object : Handler() {

    override fun handleMessage(msg: Message?) {
        // Your logic code here.
    }
}

Update: As @BeniBela's comment, when using above code, a lint warning will be displayed

This Handler class should be static or leaks might occur.

Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue.

If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follows: Declare the Handler as a static class; In the outer class, instantiate a WeakReference to the outer class and pass this object to your Handler when you instantiate the Handler; Make all references to members of the outer class using the WeakReference object.

class OuterClass {

    // In the outer class, instantiate a WeakReference to the outer class.
    private val outerClass = WeakReference<OuterClass>(this)

    // Pass the WeakReference object to the outer class to your Handler
    // when you instantiate the Handler
    private val mMyHandler = MyHandler(outerClass)

    private var outerVariable: String = "OuterClass"

    private fun outerMethod() {

    }

    // Declare the Handler as a static class.
    class MyHandler(private val outerClass: WeakReference<OuterClass>) : Handler() {

        override fun handleMessage(msg: Message?) {
            // Your logic code here.
            // ...

            // Make all references to members of the outer class 
            // using the WeakReference object.
            outerClass.get()?.outerVariable
            outerClass.get()?.outerMethod()
        }
    }
}
Paraboloid answered 26/8, 2018 at 10:22 Comment(2)
This gives a HandlerLeak lint warningMithras
@Mithras thanks for your info, please check my updated answer.Paraboloid
C
16

You may do it a bit easier (without WeakReference) by passing looper to handler:

val handler = object:  Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            doStuff()
        }
    }
Cianca answered 7/11, 2019 at 11:35 Comment(0)
P
2

In my case :

@SuppressLint("HandlerLeak")
    private inner class MessageHandler(private val mContext: Context) : Handler() {
        override fun handleMessage(msg: Message) {
            when (msg.what) {

            }
        }
    }
Paralysis answered 26/8, 2018 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.