Android应用生命周期实现简单的秒表App
文章目錄
- 1、功能分析
- 1.1、秒表功能界面
- 1.2、App結(jié)構(gòu)
- 2、開發(fā)視圖布局
- 2.1、activity_main.xml
- 2.2、string.xml
- 3、Activity實現(xiàn)
- 3.1、MainActivity類
- 4、生命周期的應(yīng)用
- 4.1、問題分析
- 4.2、Activity運(yùn)行過程
- 4.2、屏幕旋轉(zhuǎn),計時不重置
- 4.3、App被切換至后臺,秒表可以暫停
- 5、MainActivity完整代碼
1、功能分析
1.1、秒表功能界面
1.2、App結(jié)構(gòu)
- 1個Activity :MainActivity
- 1個Layout :activity_main.xml
2、開發(fā)視圖布局
2.1、activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_horizontal"android:orientation="vertical"><TextViewandroid: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"/><Buttonandroid: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"/><Buttonandroid: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"/><Buttonandroid: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>2.2、string.xml
<resources><string name="app_name">Stopwatch</string><string name="start">start</string><string name="stop"> Stop</string><string name="reset">Reset</string><string name="time">Time</string> </resources>3、Activity實現(xiàn)
3.1、MainActivity類
public class MainActivity extends AppCompatActivity {//計時的秒數(shù)private int seconds = 0;//計時的狀態(tài)private boolean running = false;@Overrideprotected 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;}//循環(huán)計時方法private void runTimer(){final TextView timeView = findViewById(R.id.time_view);//創(chuàng)建UI線程的handler,用于消息處理final Handler handler = new Handler();handler.post(new Runnable() {//立即交一個Runnable,任務(wù)在Runnable的run()方法中@Overridepublic 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,重復(fù)提交該任務(wù)handler.postDelayed(this,1000);}});} }4、生命周期的應(yīng)用
4.1、問題分析
- 問題一:旋轉(zhuǎn)屏幕,Android檢測到屏幕方向變化,計時會重置
- 問題二:App被切換至后臺,秒表不能暫停
4.2、Activity運(yùn)行過程
4.2、屏幕旋轉(zhuǎn),計時不重置
-
設(shè)備配置變化時,如屏幕旋轉(zhuǎn),需保存狀態(tài),重啟時恢復(fù)
-
在運(yùn)行后(running),銷毀(onDestroy())前會調(diào)用 onSaveInstanceState(),保存狀態(tài)到Bundle
-
保存狀態(tài)需要覆蓋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()方法中恢復(fù),Bundle是其參數(shù),進(jìn)程第一次新建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(); }
-
-
程序運(yùn)行流程
- 用戶啟動App,點擊start按鈕,開始計時
runTimer()方法開始遞增seconds,并顯示到文本框time_view中 - 旋轉(zhuǎn)手機(jī),Android檢測到屏幕方向變化,銷毀原Activity前,調(diào)用onSaveInstanceState()保存實例變量
- Android銷毀Activity,再次新建該Activity再次調(diào)用onCreate()方法,將保存的Bundle作為參數(shù)傳入
- onCreate()方法中,取出Bundle存儲的值并恢復(fù)到銷毀前的狀態(tài)
- runTimer()方法從旋轉(zhuǎn)前的seconds繼續(xù)計時
- 用戶啟動App,點擊start按鈕,開始計時
4.3、App被切換至后臺,秒表可以暫停
-
解決方法
-
覆蓋onStop(),在消失前停止計時
@Override protected void onStop(){super.onStop();Log.d("life cycle","onStop");wasRunning = running; // 記錄之前是否運(yùn)行,running = false; //將running設(shè)置為false以停止計時 } -
覆蓋生命周期方法前,必須先調(diào)用父類的生命周期
super.onStop();
-
覆蓋onStart(),在可見前繼續(xù)計時
@Override //如果之前running==true,則將running設(shè)置為true,繼續(xù)計時 protected void onStart(){super.onStart();Log.d("life cycle","onStop");if(wasRunning){ running = true;} } -
App被切換至后臺,Activity對象仍存在,可以使用實例變量存儲狀態(tài)
//計時的秒數(shù) private int seconds = 0; //計時的狀態(tài) private boolean running = false; //新的變量,用于在onStop()中保存消失前running的狀態(tài) 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"); //日志并恢復(fù)if(wasRunning){running = true;} } -
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); }
Activity重新實例化后從Bundle恢復(fù)wasRunning
-
-
運(yùn)行流程
- 用戶啟動App,點擊Start按鈕,runTimer()開始遞增seconds并更新文本框
- 用戶點擊Home鍵,Activity消失,Android調(diào)用onStop()
- 用戶返回秒表App,Activity可見,Android調(diào)用onStart()
5、MainActivity完整代碼
public class MainActivity extends AppCompatActivity {//計時的秒數(shù)private int seconds = 0;//計時的狀態(tài)private boolean running = false;//新的變量,用于在onStop()中保存消失前running的狀態(tài)private boolean wasRunning = false;@Overrideprotected 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();}@Overrideprotected void onStart(){super.onStart();Log.d("life cycle","onStop");if(wasRunning){running = true;}}@Overrideprotected void onStop(){super.onStop();Log.d("life cycle","onStop");wasRunning = running;running = false;}@Overridepublic 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;}//循環(huán)計時方法private void runTimer(){final TextView timeView = findViewById(R.id.time_view);//創(chuàng)建UI線程的handler,用于消息處理final Handler handler = new Handler();handler.post(new Runnable() {//立即交一個Runnable,任務(wù)在Runnable的run()方法中@Overridepublic 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,重復(fù)提交該任務(wù)handler.postDelayed(this,1000);}});} }總結(jié)
以上是生活随笔為你收集整理的Android应用生命周期实现简单的秒表App的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ABAP-面试中的奇葩问题
- 下一篇: 简易秒表Android源代码