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
对象,因此您可以添加回调或删除已发布的
我是 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
对象,因此您可以添加回调或删除已发布的