Android開發--Activity生命週期回顧理解
Activity和Servlet一樣,都用了回撥機制。我們通過類比servlet來學習Activity。當一個servlet開發出來之後,該servlet運行於Web伺服器中。伺服器何時建立servlet的例項,何時呼叫servlet的方法向用戶生成響應,程式設計師無法控制,這種回撥由伺服器自行決定。Activity也一樣,被開發出來,開發者只要在AndroidManifest.xml檔案配置該Activity即可。至於該Activity何時被例項化,它的方法何時被呼叫,對開發者來說完全是透明的。
當開發者開發一個Servlet時,根據不同的需求場景,可能需要選擇性的的實現如下方法:
- init(servletConfig config)
- destroy()
- doGet(HttpServletRequest req,HttpServletResponse resp)
- doPost(HttpServletRequest req,HttpServletResponse resp)
- sevice(HttpServletRequest req,HttpServletResponse resp
- 當把Servlet部署到Web應用中之後,Web伺服器將會在特定的時刻,呼叫該Servlet上面的各種方法---這種呼叫就被稱為回撥。
Activity的回到機制與此類似,當Activity被部署到Android應用之後,隨著應用程式的執行,Activity會不斷的在不同的狀態進行切換,該activity中特定的方法就會被回撥-----開發者就可以選擇性的重寫這些方法來加入業務相關的處理
Android的生命週期:當activity處於Android的應用中的執行時,它的活動狀態由Android執行時以Activity棧的形式管理。當前活動的Activity位於棧頂。
Android的生命週期演示:android大致經過如下四個狀態:
- 活動狀態:當前Activity位於前臺,使用者可見,可以獲得焦點。
- 暫停狀態:其他Activity位於前臺,該Activity依然可見,只是不能獲得焦點。
- 停止狀態:該Activity不可見,失去焦點
- 銷燬裝填:該activity結束,或者activity所在的Dalvik程序被結束。
下面是官方API所提供的生命週期圖:
下面使用程式碼親自測下Android的生命週期,測完就明白了:
package com.lp.ecjtu.activitydemo1; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.Menu; import android.widget.EditText; public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private EditText editText; //建立Activity被回撥 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (EditText) findViewById(R.id.editText); Log.e(TAG, "Start onCreate ========="); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } //啟動Activity被回撥 @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Log.e(TAG, "Start onStart ========="); } //重新啟動Activity被回撥 @Override protected void onRestart() { // TODO Auto-generated method stub super.onRestart(); Log.e(TAG, "Start onRestart ========="); } //恢復Activty被回撥 @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); Log.e(TAG, "Start onResume ========="); } //暫停Activity被回撥 @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); Log.e(TAG, "start onPause============="); } //停止Activity被回撥 @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); Log.e(TAG, "start onStop============="); } //銷燬Activity被回撥 @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.e(TAG, "start onDestroy============="); } }
執行上面的程式碼:我們開啟應用程式時回調了OnCreate()-->onStart()-->onResume()方法。在LogCat視窗可以看到:
Back鍵:當我們按返回鍵的時候這個應用程式或者Activity將結束,依次回調了OnPause()-->onStop()-->Ondestroy()方法:在LogCat視窗可以看到:
HOME鍵:當我們正在打遊戲的時候,突然來了條簡訊,我們想看短息,按HOME鍵,然後開啟簡訊的應用,當我們按HOME鍵的時候Activity先後執行了OnPause()-->OnStop方法,在LogCat視窗可以看到:
而我們看完短息在啟動應用的時候:會執行OnRestart()-->onStart-->OnResume方法。在LogCat視窗可以看到:
通過上面的操作,想必我們都對Android Activity生命週期有了深刻的瞭解,我們就可以在開發Activity的時候,選擇性的重寫生命週期的方法來解決業務上的一些需求。
例如:下面的這個例子,當我們在看視屏的時候,或者在註冊的時候,剛好填完使用者的註冊資訊,不小心按到了Home鍵,當我們在進入應用程式的時候,發現之前填的註冊資訊全沒了,這時候我們就要哭了,說明這個應用程式做的比較垃圾。正常情況下,我們之前填寫的註冊資訊還在,也就是說和我們按Home鍵之前的狀態是一致的。
為了理解,我們用一個小例子說明問題:
在XML程式碼程式碼中增加EditText:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello_Activity" /> <EditText android:id="@+id/editText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:ems="10" /> </LinearLayout>
java程式碼不變,執行程式,在EditText中輸入peter,
然後按HOME鍵,在次啟動MainActivity,發現之前輸入的內容沒了。
這顯然不是正常的應用程式,我們都會哭的。那麼就需要我們隊生命週期非常瞭解了,當我們按Home鍵的時候,Activity回調了onPause-->OnStop()方法,再次進入應用程式的時候回調了OnRestart-->OnStart-->onResume()方法,說明我們只要在onPause()和OnRestart方法裡面做處理既可以儲存之前的狀態:下面看程式碼
package com.lp.ecjtu.activitydemo1; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.Menu; import android.widget.EditText; public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private EditText editText; //定義一個String字串用於存放使用者輸入的字串 private String userString; //建立Activity被回撥 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (EditText) findViewById(R.id.editText); Log.e(TAG, "Start onCreate ========="); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } //啟動Activity被回撥 @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Log.e(TAG, "Start onStart ========="); } //重新啟動Activity被回撥 @Override protected void onRestart() { // TODO Auto-generated method stub super.onRestart(); //再次啟動應用時,把先前使用者輸入的值重新設定EditText editText.setText(userString); Log.e(TAG, "Start onRestart ========="); } //恢復Activty被回撥 @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); Log.e(TAG, "Start onResume ========="); } //暫停Activity被回撥 @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); //按home鍵的時候,儲存使用者輸入的字串資訊。 userString = editText.getText().toString(); Log.e(TAG, "start onPause============="); } //停止Activity被回撥 @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); Log.e(TAG, "start onStop============="); } //銷燬Activity被回撥 @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.e(TAG, "start onDestroy============="); } }
重新啟動app,按home鍵,在進入應用程式OK了,看下面的圖:
總結:理解生命週期的關鍵是,我們可以在開發過程選擇性的重寫生命週期中的方法,解決一些實際問題,這才是關鍵,學以致用!
Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear. 面對過去無怨無悔,把握現在充滿信心,備戰未來無所畏懼。保持信念,克服恐懼!一點一滴的積累,一點一滴的沉澱,學技術需要不斷的積澱!