我希望countdowntimer在一个单独的线程上,并让它在每个tick上更新UI。每次我点击启动应用程序只是关闭,我得到'应用程序已停止'错误消息。
public class Activity_MultiplayerGame extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity__multiplayer_game);
}
public void btnStart_onClick(View view){
CountDownTimer timer = new CountDownTimer(15000, 1000){
@Override
public void onTick(final long millisUntilFinished) {
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView countdownText = (TextView) findViewById(R.id.countdown);
Integer timeUntilFinished = (int) millisUntilFinished/1000;
countdownText.setText(timeUntilFinished);
}
});
}
@Override
public void onFinish() {
TextView countdownText = (TextView) findViewById(R.id.countdown);
countdownText.setText("Finished");
}
};
timer.start();
}
}
我已经假设创建一个CountDownTimer给它自己的线程?
你可以使用Handler。我为你写了一个样本
此代码每隔一秒增加一个计数器,并在textView上显示和更新计数器值。
public class MainActivity extends Activity {
private Handler handler = new Handler();
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text);
startTimer();
}
int i = 0;
Runnable runnable = new Runnable() {
@Override
public void run() {
i++;
textView.setText("counter:" + i);
startTimer();
}
};
public void startTimer() {
handler.postDelayed(runnable, 1000);
}
public void cancelTimer() {
handler.removeCallbacks(runnable);
}
@Override
protected void onStop() {
super.onStop();
cancelTimer();
}
}
这是你的问题:
countdownText.setText(timeUntilFinished);
您已将整数传递给setText(int)
方法,该方法实际上需要显示字符串资源ID而不是整数。你应该使用方法setText(String)
。
试试这个:
countdownText.setText(String.valueOf(timeUntilFinished));
此代码也可以减少计数器(或增加任何你想要的),并在文本视图中显示您也可以通过单击相同的按钮停止或重置计数器。
public class MainActivity extends AppCompatActivity {
TextView textView;
Button count;
boolean timelapseRunning = true;
int NUM_OF_COUNT=15;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textview);
count=(Button)findViewById(R.id.count);
runTimer();
}
public void onclick(View view){
if (!timelapseRunning) {
timelapseRunning=true;
} else {
timelapseRunning = false;
}
if(NUM_OF_COUNT==0){
NUM_OF_COUNT=15;
}
}
private void runTimer() {
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
textView.setText(""+NUM_OF_COUNT);
if (!timelapseRunning && NUM_OF_COUNT>0) {
NUM_OF_COUNT--;
}
handler.postDelayed(this, 1000);
}
});
}
}
CountDownTimer
在创建它的同一个线程上发出回调。因此,如果在UI线程上调用runOnUiThread
构造函数,则绝对不需要onTick
中的CountDownTimer
。
也,
TextView countdownText = (TextView) findViewById(R.id.countdown);
在onTick方法中被调用的设计很差,因为findViewById
方法消耗了相当大的处理能力。
最后,Nabin Bhandari指出的实际问题是传递给setText
方法的整数值。你需要将它包装成字符串。这段代码就足够了
final TextView countdownText = (TextView) findViewById(R.id.countdown);
CountDownTimer timer = new CountDownTimer(15000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
countdownText.setText(String.valueOf(millisUntilFinished/1000));
}
@Override
public void onFinish() {
countdownText.setText("Finished");
}
};
timer.start();