So I'm trying to write a stopwatch app that displays time in milliseconds, but for some reason it won't work. Basically I have just a togglebutton that, after being pressed, starts printing the milliseconds from the start time to the current time... In the simulator though, the app locks up. What's wrong?
public class testing extends Activity {
/** Called when the activity is first created. */
Button start,stop;
long init,now,time;
TextView display;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
display = (TextView) findViewById(R.id.chronometer1);
final ToggleButton passTog = (ToggleButton) findViewById(R.id.onoff);
passTog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
init=System.currentTimeMillis();
while(passTog.isChecked())
{
now=System.currentTimeMillis();
time=now-init;
display.setText("t: " + time);
}
}
});
}
}
You definitely should not run a busy loop like you are doing inside the OnClickListener. That's why the app locks up. You need to let the rest of the system have its say. Also, it doesn't make sense to update the display more than once every 30 milliseconds or so, since that's about the fastest that the human eye can track. Also, you might want to suspend your timer when the activity is paused. Here's a version that does all that:
public class testing extends Activity {
/** Called when the activity is first created. */
Button start,stop;
long init,now,time,paused;
TextView display;
Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler();
setContentView(R.layout.test);
display = (TextView) findViewById(R.id.chronometer1);
final ToggleButton passTog = (ToggleButton) findViewById(R.id.onoff);
final Runnable updater = new Runnable() {
@Override
public void run() {
if (passTog.isChecked()) {
now=System.currentTimeMillis();
time=now-init;
display.setText("t: " + time);
handler.postDelayed(this, 30);
}
}
};
passTog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
init = System.currentTimeMillis();
handler.post(updater);
}
});
}
@Override
protected void onPause() {
super.onPause();
paused = System.currentTimeMillis();
}
@Override
protected void onResume() {
super.onResume();
init += System.currentTimeMillis() - paused;
}
}