接續上篇
使用Handler和Thread作為遊戲的計時器
var handler = Handler(Handler.Callback {
when (it.what) {
1 -> {
//m和s是外部變數,代表分秒
tv_time.text = String.format("%02d:%02d", m, s)
}
}
true
})
fun timer() {
Thread(Runnable {
while(s+m !=0){
Thread.sleep(1000)
s--
if(s==-1){
m--
s=59
}
val msg= Message()
msg.what = 1
handler.sendMessage(msg)
}
//當時間到時重設畫面
reset()
}).start()
}
另一個可以進行非同步執行的類別,結合了Thread、Message和Handler,可以方便地和Main Thread進行溝通,所以常用在進度條的更新
有三個需要override的方法
fun gameStart() {
//傳入的三個參數代表:輸入的型別、進度更新的型別、結果回傳的型別
object : AsyncTask<Void,Void,Int>(){
override fun doInBackground(vararg p0: Void?) :Int{
//以防最後一秒還產生新的畫面
//所以提早三秒結束
while(!(s<=3 && m==0)){
//隨機延遲1~3秒
Thread.sleep((Math.random()*3+1).toLong()*1000)
//若在延遲期間計時器已歸零 則直接結束迴圈
if(s<=3 && m==0)
break
//啟動onProgressUpdate
publishProgress()
}
return 0
}
override fun onProgressUpdate(vararg values: Void?) {
//產生新的畫面
newRound()
}
override fun onPostExecute(result: Int?) {
//讓TextView可以點選
tv_time.isClickable = true
tv_time.text = "重新開始"
}
}.execute()
}
這邊把顯示時間的TextView當作開始遊戲的按鈕
tv_time.setOnClickListener {
//讓TextView無法點選
tv_time.isClickable = false
m = 1
s = 0
timer()
gameStart()
}