我是来自奥地利的阿洛伊斯。三天前,我开始使用 Kotlin 在智能手机上编写应用程序,所以几乎没有粘合剂。我只知道 vb.net 是我 15 年前开始使用的最新编程语言。所以希望我的英语足够好来详细解释我的问题。
作为我的第一个应用程序,我想实现我儿子的一个想法。它应该成为一个小游戏。 在屏幕上,您可以在底部看到 3 个按钮(SPEED、UPGRADE 和 INCOME),中间顶部有一个 textView (mytxt),中间有一个 imageView。
每一个特定的时间段(从1秒开始)你都会赚钱,所以每一秒你都会得到1件。我想用定时器/定时器任务来编程。当我按下 SPEED 按钮时,时间段将变短(以 100ms 为步长)。但这是我的第一个困难,按下这个按钮程序就崩溃了,没有错误输出。
请有人检查我的代码并帮助我解决这个问题吗?
提前非常感谢。 阿洛伊斯
package com.example.uyc_android
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import java.util.Timer
import java.util.TimerTask
var money=0
var timerperiod: Long= 1000
var computerType=1
var income =1
class MainActivity : AppCompatActivity() {
private lateinit var timer: Timer
private lateinit var timerTask: TimerTask
private var counter = 0
@SuppressLint("SetTextI18n")
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mytxt = findViewById<TextView>(R.id.txtMoney)
val btnSpeed = findViewById<Button>(R.id.btnSpeed)
val btnUpgrade = findViewById<Button>(R.id.btnUpgrade)
val btnIncome = findViewById<Button>(R.id.btnIncome)
val bild = findViewById<ImageView>(R.id.imagePC)
timer = Timer()
var timerTask = object : TimerTask() {
override fun run() {
counter++
// Aktualisiere den Wert auf der Benutzeroberfläche im UI-Thread
runOnUiThread {
mytxt.text = counter.toString()
}
}
}
timer.schedule(timerTask, 0, timerperiod)
btnSpeed.setOnClickListener {
timerperiod -= 100L
if (timerperiod <= 100L) {
timerperiod = 100L
}
timerTask.cancel()
timer.schedule(timerTask, 0, timerperiod)
runOnUiThread { btnSpeed.text = "SPEED ${timerperiod}" }
}
btnUpgrade.setOnClickListener {
computerType++
if (computerType >= 3) {
computerType = 3
}
if (computerType == 1) {
runOnUiThread { bild.setTag(R.drawable.pc1) }
}
if (computerType == 2) {
runOnUiThread { bild.setTag(R.drawable.pc2) }
}
if (computerType == 3) {
runOnUiThread { bild.setTag(R.drawable.pc3) }
}
runOnUiThread { btnUpgrade.text = "UPGRADE ${computerType}" }
}
btnIncome.setOnClickListener {
income++
runOnUiThread { btnIncome.text = "INCOME ${income}" }
}
}
}
我在www上搜索了很多。我看了很多教程但没有结果。也许有人可以更改我的代码,使其有效。
您无法重用TimerTask实例,因此每次都必须创建一个新实例。由于它仅在
onCreate()
内部使用,因此您可以在onCreate()
内部定义创建者函数。
顺便说一句,您对
runOnUiThread { }
的所有使用都是不必要的,因为计时器和按钮侦听器回调已经始终在 UI 线程上调用。
fun createTimerTask() = object : TimerTask() {
override fun run() {
counter++
mytxt.text = counter.toString()
}
}
var timerTask = createTimerTask()
timer.schedule(timerTask, 0, timerperiod)
btnSpeed.setOnClickListener {
timerperiod -= 100L
if (timerperiod <= 100L) {
timerperiod = 100L
}
timerTask.cancel()
timerTask = createTimerTask() // <---------------
timer.schedule(timerTask, 0, timerperiod)
btnSpeed.text = "SPEED ${timerperiod}"
}
顺便说一下,这个:
timerperiod -= 100L
if (timerperiod <= 100L) {
timerperiod = 100L
}
可以简化为:
timerPeriod = max(timerPeriod - 100L, 100L)
您的升级按钮侦听器代码可以简化为:
btnUpgrade.setOnClickListener {
computerType = min(computerType + 1, 3)
btnUpgrade.text = "UPGRADE ${computerType}"
val tag = when (computerType) {
1 -> R.drawable.pc1
2 -> R.drawable.pc2
3 -> R.drawable.pc3
else -> return
}
bild.setTag(tag)
}