android中Activity詳解(生命周期、以各種方式啟動Activity、狀態(tài)保存,完全退出等)
一、什么是Activity?
簡單的說:Activity就是布滿整個窗口或者懸浮于其他窗口上的交互界面。在一個應(yīng)用程序中通常由多個Activity構(gòu)成,都會在Manifestxml中指定一個主的Activity,如下設(shè)置
<actionandroid:name="AndroidintentactionMAIN" />
當(dāng)程序第一次運行時用戶就會看這個Activity,這個Activity可以通過啟動其他的Activity進行相關(guān)操作。當(dāng)啟動其他的Activity時這個當(dāng)前的這個Activity將會停止,新的Activity將會壓入棧中,同時獲取用戶焦點,這時就可在這個Activity上操作了。都知道棧是先進后出的原則,那么當(dāng)用戶按Back鍵時,當(dāng)前的這個Activity銷毀,前一個Activity重新恢復(fù)。
二、Activity生命周期
先看下圖:
這個圖不再多說什么,下面我們通過一個實例來說明問題。新建工程,編寫如下代碼:
<span style="font-size: 18px;">package comandroidttxactiitylifedemo; import androidappActivity; import androidosBundle; import androidutilLog; import androidviewKeyEvent; public class ActivityLifeDemo extends Activity { private final static String TAG="ActivityLifeDemo"; @Override public void onCreate(Bundle savedInstanceState) { superonCreate(savedInstanceState); setContentView(Rlayoutmain); Logi(TAG, "onCreate"); } @Override protected void onStart() { Logi(TAG, "onStart"); superonStart(); } @Override protected void onRestart() { Logi(TAG, "onRestart"); superonRestart(); } @Override protected void onResume() { Logi(TAG, "onResume"); superonResume(); } @Override protected void onPause() { Logi(TAG, "onPause"); superonPause(); } @Override protected void onStop() { Logi(TAG, "onStop"); superonStop(); } @Override protected void onDestroy() { Logi(TAG, "onDestroy"); superonDestroy(); } } </span>
代碼很簡單,只涉及到一個Activity,一些用戶的操作,我們通過記錄操作和打印日志的方式來看看Activity的生命周期過程。
1、 運行
看到如下打印日志:
08-31 08:46:916: INFO/ActivityLifeDemo(312): onCreate
08-31 08:46:916: INFO/ActivityLifeDemo(312): onStart
08-31 08:46:916: INFO/ActivityLifeDemo(312): onResume
2、按下返回按鍵:
08-31 09:29:396: INFO/ActivityLifeDemo(354): onPause
08-31 09:29:216: INFO/ActivityLifeDemo(354): onStop
08-31 09:29:216: INFO/ActivityLifeDemo(354): onDestroy
3、長按Home鍵,彈出最近打開過的應(yīng)用程序,點擊ActivityLifeDemo
08-31 08:51:916: INFO/ActivityLifeDemo(312): onCreate
08-31 08:51:916: INFO/ActivityLifeDemo(312): onStart
08-31 08:51:936: INFO/ActivityLifeDemo(312): onResume
4、按Home鍵
08-31 08:53:676: INFO/ActivityLifeDemo(312): onPause
08-31 08:53:796: INFO/ActivityLifeDemo(312): onStop
5、在AllList中點擊打開
08-31 08:54:286: INFO/ActivityLifeDemo(312): onRestart
08-31 08:54:286: INFO/ActivityLifeDemo(312): onStart
08-31 08:54:296: INFO/ActivityLifeDemo(312): onResume
通過日志信息,我們可以看到。Activity的啟動過程:onCreate—onStart—onResume;下返回鍵時:onPause—onStop—onDestroy 正如上面說是,當(dāng)按下返回鍵時,此Activity彈出棧,程序銷毀。確實如此,我們再次 打開時的啟動過程又回到onCreate—onStart—onResume。OK,啟動之后按下Home鍵,回到Launcher,查看打印信息:onPause—onStop,再次打開的運行過程:onRestart—onStart—onResume。
我們通過對Activity的各種操作,構(gòu)成了Activity的生命周期,我們看到無論對Activity做如何的操作,都會接收到相關(guān)的回調(diào)方法,那么我們在開發(fā)的過程中通過這些回調(diào)方法就可以寫工作,比如說釋放一些重量級的對象,網(wǎng)絡(luò)連接,數(shù)據(jù)庫連接,文件讀等等。
以下是各個方法的詳細說明:
onCreate():當(dāng) activity 第一次創(chuàng)建時會被調(diào)用。在這個方法中你需要完成所有的正常靜態(tài)設(shè)置 ,比如創(chuàng)建一個視圖( view )、綁定列表的數(shù)據(jù)等等。如果能捕獲到 activity 狀態(tài)的話,這個方法傳遞進來的 Bundle 對象將存放了 activity 當(dāng)前的狀態(tài)。調(diào)用該方法后一般會調(diào)用 onStart() 方法。
onRestart():在 activity 被停止后重新啟動時會調(diào)用該方法。其后續(xù)會調(diào)用 onStart 方法。
onStart()à當(dāng) activity 對于用戶可見前即調(diào)用這個方法。如果 activity回到前臺則接著調(diào)用 onResume() ,如果 activity 隱藏則調(diào)用onStop()
onResume():在 activity 開始與用戶交互前調(diào)用該方法。在這時該activity 處于 activity 棧的頂部,并且接受用戶的輸入。其后續(xù)會調(diào)用 onPause() 方法。
onPause():在系統(tǒng)準備開始恢復(fù)其它 activity 時會調(diào)用該方法。這個方法中通常用來提交一些還沒保存的更改到持久數(shù)據(jù) 中,停止一些動畫或其它一些耗 CPU 的操作等等。無論在該方法里面進行任何操作,都需要較快速完成,因為如果它不返回的話,下一個 activity 將無法恢復(fù)出來。如果 activity 返回到前臺將會調(diào)用 onResume() ,如果 activity 變得對用戶不可見了將會調(diào)用onStop() 。
onStop():在 activity 對用戶不可見時將調(diào)用該方法??赡軙驗楫?dāng)前 activity 正在被銷毀,或另一個 activity (已經(jīng)存在的activity 或新的 activity )已經(jīng)恢復(fù)了正準備覆蓋它,而調(diào)用該方法。如果 activity 正準備返回與用戶交互時后續(xù)會調(diào)用onRestart ,如果 activity 正在被釋放則會調(diào)用 onDestroy 。
onDestroy():在 activity 被銷毀前會調(diào)用該方法。這是 activity 能接收到的最后一個調(diào)用??赡軙驗橛腥苏{(diào)用了 finish 方法使得當(dāng)前activity 正在關(guān)閉,或系統(tǒng)為了保護內(nèi)存臨時釋放這個 activity的實例,而調(diào)用該方法。你可以用 isFinishing 方法來區(qū)分這兩種不同的情況。
三、如何啟動一個新的Activity?
要啟動一個新的Activity,我們可以通過調(diào)用Context中的startActivity來啟動。像這樣:
<span style="font-size: 18px;">Intent intent = new Intent(this, ActivityDemoclass); startActivity(intent); // ActivityDemo是需要啟動的Activity類 </span>
通過上面的方法可以啟動新的Activity了,但如果我要從當(dāng)前的Activity中傳遞數(shù)據(jù)到新的Activity呢?很簡單:
<span style="font-size: 18px;">Intent intent = new Intent(this,ActivityDemoclass); Bundle bundle = new Bundle(); bundleputBoolean("bool_key", true); intentputExtras(bundle); startActivity(intent); </span>
還有,有時候我們需要啟動帶返回值的Activity,簡單的說就是需要新啟動的Activity返回時將值傳遞給啟動它的Activity,像這樣:
<span style="font-size: 18px;">Intent intent = new Intent(ActivityLifeDemothis,RevalueActivityclass); startActivityForResult(intent, 0x1001); </span>
ActivityLifeDemo是當(dāng)前的Activity,啟動RevalueActivity,我們在ActivityLifeDemo中需要獲取RevalueActivity傳回來的值。那么在RevalueActivity中就必須這樣寫:
<span style="font-size: 18px;">Intent intent = new Intent(); intentputExtra("revalue_key","haha-revalueActivity"); setResult(0x1001, intent);</span>
那么“revalue_key”值在哪里獲取呢?必須重寫onActivityResult方法,通過判斷requestCode,來確定
<span style="font-size: 18px;">if(requestCode==0x1001){ String str = datagetStringExtra("revalue_key"); Logi(TAG, "返回的值為:"+str); } </span>
好了,詳細的請看代碼吧。下載地址:http://xiazai.jb51.net/201611/yuanma/ActivityLifeDemo_jb51.rar
四、保存Activity運行狀態(tài)
通過重寫onSaveInstanceState()方法來實現(xiàn)Activity的運行狀態(tài),請注意以下幾點:
1)由于activity 對象被暫?;蛲V箷r,它仍然保留在內(nèi)存里面,關(guān)于它的成員信息和當(dāng)前狀態(tài)都是活動的,所以此時可以保存Activity的狀態(tài),從而使用戶所作的Activity的更改保存在內(nèi)存中
2) 當(dāng)系統(tǒng)回收內(nèi)存而將Activity銷毀時,就無法保存其狀態(tài),所以需要調(diào)用onSaveInstanceState()方法來實現(xiàn)狀態(tài)的保存
3) 很多情況并不需要保持狀態(tài)信息,比如按下返回鍵直接關(guān)閉程序,所以并不能保證會調(diào)用onSaveInstanceState。如果調(diào)用了該方法,一般是在onStop 方法之前且可能在 onPause 之后調(diào)用。盡管如此,即使你沒做任何操作或沒有實現(xiàn) onSaveInstanceState() 方法,你的 activity 狀態(tài)也能通過Activity 類里面默認實現(xiàn)的 onSaveInstanceState 方法恢復(fù)出來。特別是會為布局中的視圖( View )默認調(diào)用onSaveInstanceState 方法,并在這個方法中允許每一個視圖提供它需要恢復(fù)的任何信息。幾乎每一個 Android框架中的 widget 都視情況實現(xiàn)了這個方法。
注:因為 onSaveInstanceState 方法不一定會被調(diào)用,所以你應(yīng)該只是用它來保存一些 activity 的轉(zhuǎn)換過程狀態(tài)(即 UI 的狀態(tài)),而不能用來保存永久性數(shù)據(jù)。但你可以用 onPause 方法在用戶離開 activity 時來保存永久性數(shù)據(jù),比如需要保存到數(shù)據(jù)庫的數(shù)據(jù)。
有一個很好的方法可以用來檢驗應(yīng)用程序保存狀態(tài)的能力,就是簡單地旋轉(zhuǎn)你的設(shè)備來改變屏幕的方向。因為當(dāng)屏幕方向改變時,系統(tǒng)為了給新的方向提供一個可能合適的代替資源,會銷毀 activity 并新建一個新的。由于這個原因,你的 activity 是否能在其重新創(chuàng)建時完成保存狀態(tài)就顯得尤為重要,因為用戶經(jīng)常會在使用應(yīng)用程序時旋轉(zhuǎn)屏幕的。
五、完全退出程序
通過上面的介紹,我們知道當(dāng)點擊back鍵時,程序調(diào)用了onDestroy方法,程序退出了,但是我們查看其進程,發(fā)現(xiàn)調(diào)用了onDestroy方法之后這個Activity還在運行。甚至調(diào)用了finish()方法之后程序還能在進程中看到。通過下面這種方式可以實現(xiàn)程序的完全退出:
<span style="font-size: 18px;">Intent intent = new Intent(); IntentsetClass(context,MainActivityclass); intentsetFlags(IntentFLAG_ACTIVITY_CLEAR_TOP); intentputExtra(“flag”,EXIT_APPLICATION); contextstartActivity(intnet); </span>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
android 中ProgressDialog實現(xiàn)全屏效果的示例
本篇文章主要介紹了android 中ProgressDialog實現(xiàn)全屏效果的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11Android控件gridview實現(xiàn)單行多列橫向滾動效果
這篇文章主要為大家詳細介紹了Android控件gridview實現(xiàn)單行多列橫向滾動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12Android實現(xiàn)微信側(cè)滑刪除當(dāng)前頁面
這篇文章主要為大家詳細介紹了Android實現(xiàn)微信側(cè)滑刪除當(dāng)前頁面,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12Android視頻播放器屏幕左側(cè)邊隨手指上下滑動亮度調(diào)節(jié)功能的原理實現(xiàn)
這篇文章主要介紹了Android視頻播放器屏幕左側(cè)邊隨手指上下滑動亮度調(diào)節(jié)功能的原理實現(xiàn),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02adnroid已安裝應(yīng)用中檢測某應(yīng)用是否安裝的代碼實例
這篇文章主要介紹了Android怎么檢測一個應(yīng)用是否安裝的方法,大家參考使用吧2013-11-11