Kotlin 中的 Handler(getMainLooper()).removeCallbacks 问题,Android St

Problem with Handler(getMainLooper()).removeCallbacks in Kotlin, Android St

我是 Kotlin 的新手,正在使用 Handlers 和 Runnables。我编写了一个非常简单的程序,其中包含“开始”和“停止”按钮以及一个 TextView。当按下开始按钮时,这将开始递增一个写入 TextView 的 Int 变量 i。这只是继续进行,目的是让“停止”按钮停止该过程。使用 处理程序 = 处理程序() 一切正常。但是,我意识到这是贬值的,所以我已经尝试过 处理程序(Looper.getMainLooper()) 但停止按钮不起作用。 我确定有一个简单的解决方案,但我想不通。非常感谢任何帮助。 这是 activity_main.xml

中的按钮和文本视图
<TextView
    android:id="@+id/tv_number"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Number: "
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/btn_start"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="140dp"
    android:text="Start"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/btn_stop"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="50dp"
    android:text="Stop"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/btn_start" />

这是 MainActivity.kt 中有效的代码

class 主活动:AppCompatActivity() {

private lateinit var runnable: Runnable
private lateinit var handler: Handler

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    var btnStart = findViewById<Button>(R.id.btn_start)
    var btnStop = findViewById<Button>(R.id.btn_stop)
    var tvNumber = findViewById<TextView>(R.id.tv_number)

    var i: Int

    handler = Handler()

    btnStart.setOnClickListener() {
        i = 0
        runnable = Runnable {
            i += 1
            tvNumber.text = "Number: $i"
            handler.postDelayed(
                runnable,
                500
            )
        }
        handler.postDelayed(
            runnable,
            1
        )
    }

    btnStop.setOnClickListener() {
        handler.removeCallbacks(runnable)
    }
}

}

这是使用 Handler(Looper.getMainLooper()) 的代码(只是 setOnClickListener 函数 - 其余部分相同),其中停止按钮不起作用:

    btnStart.setOnClickListener() {
        i = 0
        runnable = Runnable {
            i += 1
            tvNumber.text = "Number: $i"
            Handler(Looper.getMainLooper()).postDelayed(
                runnable,
                500
            )
        }
        Handler(Looper.getMainLooper()).postDelayed(
            runnable,
            1
        )
    }

    btnStop.setOnClickListener() {
        Handler(Looper.getMainLooper()).removeCallbacks(runnable)
    }
}

}

您的 not-working 代码每次都在处理新的 Handler。在构造函数中传递相同的循环器并不意味着这个对象也是相同的。因此,您在新创建的 Handler 上调用 removeCallbacks,它没有发布任何回调,因此无法正常工作(不会从之前创建的 Handler 中删除并发布 runnable

顺便说一句。 afaik 在没有单个参数的情况下创建 Handler 也会在后台创建 Handler 和 main Looper 。但在第一种情况下,您引用的是一个已创建的 handler 对象,因此您可以添加回调或删除已发布的