gpt4 book ai didi

android - 如何每秒运行一个 Runnable 来更新 UI

转载 作者:行者123 更新时间:2023-11-29 02:19:55 29 4
gpt4 key购买 nike

我正在尝试在 kotlin android 中编写代码以每秒移动一个图像,但我无法使其工作。现在我正在使用 Timer 每秒安排一个 Timer Task 但它没有按预期工作。

这是我的代码

class Actvt_Image<float> : AppCompatActivity() {

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

val pict_mario = findViewById<ImageView>(R.id.img_Mario)
val bt_down = findViewById<Button>(R.id.bt_down)
val frame = findViewById<LinearLayout>(R.id.frame)
val txt1=findViewById<TextView>(R.id.txt1)

var i =100
val timer = Timer()
val myTask = object : TimerTask() {
override fun run() {

txt1.text = (i+1).toString()
img_Mario.rotation=180f
img_Mario.translationX +=100
img_Mario.translationY +=20
}
}

bt_down.setOnClickListener {

i=0
timer.schedule(myTask, 1000, 1000)

}
}

}

最佳答案

您正在尝试在不可能的后台线程上更新 UI。 UI 只能在 UI 线程上更新。此外,使用 TimerTimerTask 每 1 秒创建和销毁一个线程并不是使用线程的正确方法,因为创建线程是一项占用大量内存的操作。

您需要做的是使用 Handler 并告诉 UI Thread 在每个所需的时间间隔后运行 Runnable。删除 TimerTimerTask 并使用以下内容

val handler = Handler(Looper.getMainLooper())
handler.post(object : Runnable {
override fun run() {
txt1.text = (i+1).toString()
img_Mario.rotation=180f
img_Mario.translationX +=100
img_Mario.translationY +=20

handler.postDelayed(this, 1000)
}
})

以上代码使用处理程序并将任务发布到 UI 线程消息队列。任务本身正在更新 UI 并使用相同的处理程序再次将自己发布到 UI 线程消息队列,但这次是在延迟 1 秒后使用 handler.postDelayed() 方法

编辑:如何停止运行

如果你想停止一个特定的 runnable 你可以使用下面的方法并传入你在 handler.post() 中传递的相同的 runnable 对象。当然,您必须始终保持对 runnable 的引用才能停止它。上面的代码不保留引用。请参阅下面的完整代码

handler.removeCallbacks(runnable) //stops a specific runnable

要从 UI 线程消息队列中停止所有剩余的回调或 runnable 使用此

handler.removeCallbacksAndMessages(null) //stops any pending callback in message queue

完整代码

注意:我添加了一个停止按钮点击监听器作为补充

class Actvt_Image<float> : AppCompatActivity() {

private lateinit var handler : Handler
private lateinit var runnable : Runnable // reference to the runnable object
private var i = 0

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

val pict_mario = findViewById<ImageView>(R.id.img_Mario)
val bt_down = findViewById<Button>(R.id.bt_down)
val bt_stop = findViewById<Button>(R.id.bt_stop)
val frame = findViewById<LinearLayout>(R.id.frame)
val txt1=findViewById<TextView>(R.id.txt1)

handler = Handler(Looper.getMainLooper())
runnable = Runnable {
i++
txt1.text = i.toString()
img_Mario.rotation=180f
img_Mario.translationX +=100
img_Mario.translationY +=20
handler.postDelayed(runnable, 1000)
}

bt_down.setOnClickListener {

handler.post(runnable)

}

bt_stop.setOnClickListener {
//Use this to stop all callbacks
//handler.removeCallbacksAndMessages(null)

handler.removeCallbacks(runnable)

}
}

}

在此处阅读有关进程、线程和处理程序的更多信息: https://developer.android.com/guide/components/processes-and-threads https://developer.android.com/reference/android/os/Handler

关于android - 如何每秒运行一个 Runnable 来更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56911563/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com