<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/time_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="0:00:00"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textSize="80sp"/>
<Button
android:id="@+id/button_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/start"
android:onClick="onClickStart"/>
<Button
android:id="@+id/button_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/stop"
android:onClick="onClickStop"/>
<Button
android:id="@+id/button_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/reset"
android:onClick="onClickReset"/>
LinearLayout>
androidx.constraintlayout.widget.ConstraintLayout>
<resources>
<string name="app_name">Stopwatchstring>
<string name="start">startstring>
<string name="stop"> Stopstring>
<string name="reset">Resetstring>
<string name="time">Timestring>
resources>
public class MainActivity extends AppCompatActivity {
//计时的秒数
private int seconds = 0;
//计时的状态
private boolean running = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在Activity启动时,onCreate()方法中启动runTimer()
runTimer();
}
//启动计时
public void onClickStart(View view){
running = true;
}
//停止计时
public void onClickStop(View view){
running = false;
}
//重置秒表
public void onClickReset(View view){
running = false;
seconds = 0;
}
//循环计时方法
private void runTimer(){
final TextView timeView = findViewById(R.id.time_view);
//创建UI线程的handler,用于消息处理
final Handler handler = new Handler();
handler.post(new Runnable() {//立即交一个Runnable,任务在Runnable的run()方法中
@Override
public void run() {
int hours = seconds/3600;
int minutes = (seconds%3600)/60;
int secs = seconds%60;
String time = String.format("%d:%02d:%02d", hours, minutes, secs);
timeView.setText(time);
if(running){
seconds++;
}
//每隔1000ms,重复提交该任务
handler.postDelayed(this,1000);
}
});
}
}
设备配置变化时,如屏幕旋转,需保存状态,重启时恢复
在运行后(running),销毁(onDestroy())前会调用 onSaveInstanceState(),保存状态到Bundle
保存状态需要覆盖onSaveInstanceState()方法
Bundle可存储键值对
bundle.put*(“name”,value)
在Bundle中存储running和seconds
@Override
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("seconds",seconds);
savedInstanceState.putBoolean("running",running);
}
在onCreate()方法中恢复,Bundle是其参数,进程第一次新建Activity时为null,
之后为onSaveInstanceState()保存的Bundle
从Bundle取出键值对
bundle.get*(“name”);
在Bundle中取出running和seconds
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("life cycle","onCreate");
setContentView(R.layout.activity_main);
if(savedInstanceState!=null){
seconds = savedInstanceState.getInt("seconds");
running = savedInstanceState.getBoolean("running");
}
runTimer();
}
程序运行流程
解决方法
覆盖onStop(),在消失前停止计时
@Override
protected void onStop(){
super.onStop();
Log.d("life cycle","onStop");
wasRunning = running; // 记录之前是否运行,
running = false; //将running设置为false以停止计时
}
覆盖生命周期方法前,必须先调用父类的生命周期
super.onStop();
覆盖onStart(),在可见前继续计时
@Override
//如果之前running==true,则将running设置为true,继续计时
protected void onStart(){
super.onStart();
Log.d("life cycle","onStop");
if(wasRunning){
running = true;
}
}
App被切换至后台,Activity对象仍存在,可以使用实例变量存储状态
//计时的秒数
private int seconds = 0;
//计时的状态
private boolean running = false;
//新的变量,用于在onStop()中保存消失前running的状态
private boolean wasRunning = false;
@Override
protected void onStop(){
super.onStop();
Log.d("life cycle","onStop"); //日志并暂停
wasRunning = running;
running = false;
}
@Override
protected void onStart(){
super.onStart();
Log.d("life cycle","onStop"); //日志并恢复
if(wasRunning){
running = true;
}
}
Activity销毁前在Bundle保存wasRunning,
Activity重新实例化后从Bundle恢复wasRunning
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("life cycle","onCreate");
setContentView(R.layout.activity_main);
if(savedInstanceState!=null){
seconds = savedInstanceState.getInt("seconds");
running = savedInstanceState.getBoolean("running");
wasRunning = savedInstanceState.getBoolean("wasRunning");
}
runTimer();
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("seconds",seconds);
savedInstanceState.putBoolean("running",running);
savedInstanceState.putBoolean("wasRunning",wasRunning);
}
运行流程
public class MainActivity extends AppCompatActivity {
//计时的秒数
private int seconds = 0;
//计时的状态
private boolean running = false;
//新的变量,用于在onStop()中保存消失前running的状态
private boolean wasRunning = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("life cycle","onCreate");
setContentView(R.layout.activity_main);
if(savedInstanceState!=null){
seconds = savedInstanceState.getInt("seconds");
running = savedInstanceState.getBoolean("running");
wasRunning = savedInstanceState.getBoolean("wasRunning");
}
//在Activity启动时,onCreate()方法中启动runTimer()
runTimer();
}
@Override
protected void onStart(){
super.onStart();
Log.d("life cycle","onStop");
if(wasRunning){
running = true;
}
}
@Override
protected void onStop(){
super.onStop();
Log.d("life cycle","onStop");
wasRunning = running;
running = false;
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("seconds",seconds);
savedInstanceState.putBoolean("running",running);
savedInstanceState.putBoolean("wasRunning",wasRunning);
}
protected void onDestroy(){
super.onDestroy();
Log.d("life cycle","onDestroy");
}
//启动计时
public void onClickStart(View view){
running = true;
}
//停止计时
public void onClickStop(View view){
running = false;
}
//重置秒表
public void onClickReset(View view){
running = false;
seconds = 0;
wasTiming = false;
}
//循环计时方法
private void runTimer(){
final TextView timeView = findViewById(R.id.time_view);
//创建UI线程的handler,用于消息处理
final Handler handler = new Handler();
handler.post(new Runnable() {//立即交一个Runnable,任务在Runnable的run()方法中
@Override
public void run() {
int hours = seconds/3600;
int minutes = (seconds%3600)/60;
int secs = seconds%60;
String time = String.format("%d:%02d:%02d", hours, minutes, secs);
timeView.setText(time);
if(running){
seconds++;
}
//每隔1000ms,重复提交该任务
handler.postDelayed(this,1000);
}
});
}
}