Android四大組件介紹與生命周期_第1頁(yè)
Android四大組件介紹與生命周期_第2頁(yè)
Android四大組件介紹與生命周期_第3頁(yè)
Android四大組件介紹與生命周期_第4頁(yè)
Android四大組件介紹與生命周期_第5頁(yè)
已閱讀5頁(yè),還剩10頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Android四大組件介紹與生命周期Android四大基本組件介紹與生命周期Android四大基本組件分別是Activity,Service服務(wù),Content Provider內(nèi)容提供者,BroadcastReceiver廣播接收器。一:了解四大基本組件Activity :應(yīng)用程序中,一個(gè)Activity通常就是一個(gè)單獨(dú)的屏幕,它上面可以顯示一些控件也可以監(jiān)聽(tīng)并處理用戶的事件做出響應(yīng)。Activity之間通過(guò)Intent進(jìn)行通信。在Intent 的描述結(jié)構(gòu)中,有兩個(gè)最重要的部分:動(dòng)作和動(dòng)作對(duì)應(yīng)的數(shù)據(jù)。典型的動(dòng)作類(lèi)型有:M AIN(activity的門(mén)戶)、VIEW、PICK、EDIT 等。而

2、動(dòng)作對(duì)應(yīng)的數(shù)據(jù)則以URI 的形式進(jìn)行表示。例如:要查看一個(gè)人的聯(lián)系方式,你需要?jiǎng)?chuàng)建一個(gè)動(dòng)作類(lèi)型為VIEW 的intent,以及一個(gè)表示這個(gè)人的URI。與之有關(guān)系的一個(gè)類(lèi)叫IntentFilter。相對(duì)于intent 是一個(gè)有效的做某事的請(qǐng)求,一個(gè)intentfilter 則用于描述一個(gè)activity(或者IntentReceiver)能夠操作哪些intent。一個(gè)activity 如果要顯示一個(gè)人的聯(lián)系方式時(shí),需要聲明一個(gè)IntentFilter,這個(gè)IntentFilter 要知道怎么去處理VIEW 動(dòng)作和表示一個(gè)人的URI。IntentFilter 需要在AndroidManifest.

3、xml 中定義。通過(guò)解析各種intent,從一個(gè)屏幕導(dǎo)航到另一個(gè)屏幕是很簡(jiǎn)單的。當(dāng)向前導(dǎo)航時(shí),activity 將會(huì)調(diào)用startActivity(Intent myIntent)方法。然后,系統(tǒng)會(huì)在所有安裝的應(yīng)用程序中定義的IntentFilter 中查找,找到最匹配myIntent 的Intent 對(duì)應(yīng)的activity。新的activity 接收到myIntent 的通知后,開(kāi)始運(yùn)行。當(dāng)startActivity 方法被調(diào)用將觸發(fā)解析myIntent 的動(dòng)作,這個(gè)機(jī)制提供了兩個(gè)關(guān)鍵好處:A、Activities 能夠重復(fù)利用從其它組件中以Intent 的形式產(chǎn)生的一個(gè)請(qǐng)求;B、Activ

4、ities 可以在任何時(shí)候被一個(gè)具有相同IntentFilter 的新的Activity 取代。AndroidManifest文件中含有如下過(guò)濾器的Activity組件為默認(rèn)啟動(dòng)類(lèi)當(dāng)程序啟動(dòng)時(shí)系統(tǒng)自動(dòng)調(diào)用它 BroadcastReceive廣播接收器:你的應(yīng)用可以使用它對(duì)外部事件進(jìn)行過(guò)濾只對(duì)感興趣的外部事件(如當(dāng)電話呼入時(shí),或者數(shù)據(jù)網(wǎng)絡(luò)可用時(shí))進(jìn)行接收并做出響應(yīng)。廣播接收器沒(méi)有用戶界面。然而,它們可以啟動(dòng)一個(gè)activity或serice 來(lái)響應(yīng)它們收到的信息,或者用NotificationManager 來(lái)通知用戶。通知可以用很多種方式來(lái)吸引用戶的注意力閃動(dòng)背燈、震動(dòng)、播放聲音等。一般來(lái)說(shuō)是

5、在狀態(tài)欄上放一個(gè)持久的圖標(biāo),用戶可以打開(kāi)它并獲取消息。廣播類(lèi)型:普通廣播,通過(guò)Context.sendBroadcast(Intent myIntent)發(fā)送的有序廣播,通過(guò)Context.sendOrderedBroadcast(intent, receiverPermission)發(fā)送的,該方法第2個(gè)參數(shù)決定該廣播的級(jí)別,級(jí)別數(shù)值是在 -1000 到 1000 之間 , 值越大 , 發(fā)送的優(yōu)先級(jí)越高;廣播接收者接收廣播時(shí)的級(jí)別級(jí)別(可通過(guò)intentfilter中的priority進(jìn)行設(shè)置設(shè)為2147483647時(shí)優(yōu)先級(jí)最高),同級(jí)別接收的先后是隨機(jī)的, 再到級(jí)別低的收到廣播,高級(jí)別的或同

6、級(jí)別先接收到廣播的可以通過(guò)abortBroadcast()方法截?cái)鄰V播使其他的接收者無(wú)法收到該廣播,還有其他構(gòu)造函數(shù)異步廣播,通過(guò)Context.sendStickyBroadcast(Intent myIntent)發(fā)送的,還有sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, initialData, initialExtras)方法,該方法具有有序廣播的特性也有異步廣播的特性;發(fā)送異步廣播要: 權(quán)限,接收并處理完Intent后,廣播依然存在,直到你調(diào)用removeStickyBroadcas

7、t(intent)主動(dòng)把它去掉注意:發(fā)送廣播時(shí)的intent參數(shù)與Contex.startActivity()啟動(dòng)起來(lái)的Intent不同,前者可以被多個(gè)訂閱它的廣播接收器調(diào)用,后者只能被一個(gè)(Activity或service)調(diào)用監(jiān)聽(tīng)廣播Intent步驟:1寫(xiě)一個(gè)繼承BroadCastReceiver的類(lèi),重寫(xiě)onReceive()方法,廣播接收器僅在它執(zhí)行這個(gè)方法時(shí)處于活躍狀態(tài)。當(dāng)onReceive()返回后,它即為失活狀態(tài),注意:為了保證用戶交互過(guò)程的流暢,一些費(fèi)時(shí)的操作要放到線程里,如類(lèi)名SMSBroadcastReceiver2注冊(cè)該廣播接收者,注冊(cè)有兩種方法程序動(dòng)態(tài)注冊(cè)和Androi

8、dManifest文件中進(jìn)行靜態(tài)注冊(cè)(可理解為系統(tǒng)中注冊(cè))如下:靜態(tài)注冊(cè),注冊(cè)的廣播,下面的priority表示接收廣播的級(jí)別2147483647為最高優(yōu)先級(jí)動(dòng)態(tài)注冊(cè),一般在Activity可交互時(shí)onResume()內(nèi)注冊(cè)BroadcastReceiverIntentFilter intentFilter=new IntentFilter(vider.Telephony.SMS_RECEIVED);registerReceiver(mBatteryInfoReceiver ,intentFilter);/反注冊(cè)u(píng)nregisterReceiver(receiver);注

9、意:1.生命周期只有十秒左右,如果在 onReceive() 內(nèi)做超過(guò)十秒內(nèi)的事情,就會(huì)報(bào)ANR(Application No Response) 程序無(wú)響應(yīng)的錯(cuò)誤信息,如果需要完成一項(xiàng)比較耗時(shí)的工作 , 應(yīng)該通過(guò)發(fā)送 Intent 給 Service, 由Service 來(lái)完成 . 這里不能使用子線程來(lái)解決 , 因?yàn)?BroadcastReceiver 的生命周期很短 , 子線程可能還沒(méi)有結(jié)束B(niǎo)roadcastReceiver 就先結(jié)束了 .BroadcastReceiver 一旦結(jié)束 , 此時(shí) BroadcastReceiver 的所在進(jìn)程很容易在系統(tǒng)需要內(nèi)存時(shí)被優(yōu)先殺死 , 因?yàn)樗鼘儆诳?/p>

10、進(jìn)程 ( 沒(méi)有任何活動(dòng)組件的進(jìn)程 ). 如果它的宿主進(jìn)程被殺死 , 那么正在工作的子線程也會(huì)被殺死 . 所以采用子線程來(lái)解決是不可靠的2. 動(dòng)態(tài)注冊(cè)廣播接收器還有一個(gè)特點(diǎn),就是當(dāng)用來(lái)注冊(cè)的Activity關(guān)掉后,廣播也就失效了。靜態(tài)注冊(cè)無(wú)需擔(dān)憂廣播接收器是否被關(guān)閉,只要設(shè)備是開(kāi)啟狀態(tài),廣播接收器也是打開(kāi)著的。也就是說(shuō)哪怕app本身未啟動(dòng),該app訂閱的廣播在觸發(fā)時(shí)也會(huì)對(duì)它起作用系統(tǒng)常見(jiàn)廣播Intent,如開(kāi)機(jī)啟動(dòng)、電池電量變化、時(shí)間改變等廣播Service 服務(wù):一個(gè)Service 是一段長(zhǎng)生命周期的,沒(méi)有用戶界面的程序,可以用來(lái)開(kāi)發(fā)如監(jiān)控類(lèi)程序。比較好的一個(gè)例子就是一個(gè)正在從播放列表中播放歌

11、曲的媒體播放器。在一個(gè)媒體播放器的應(yīng)用中,應(yīng)該會(huì)有多個(gè)activity,讓使用者可以選擇歌曲并播放歌曲。然而,音樂(lè)重放這個(gè)功能并沒(méi)有對(duì)應(yīng)的activity,因?yàn)槭褂谜弋?dāng)然會(huì)認(rèn)為在導(dǎo)航到其它屏幕時(shí)音樂(lè)應(yīng)該還在播放的。在這個(gè)例子中,媒體播放器這個(gè)activity 會(huì)使用Context.startService()來(lái)啟動(dòng)一個(gè)service,從而可以在后臺(tái)保持音樂(lè)的播放。同時(shí),系統(tǒng)也將保持這個(gè)service 一直執(zhí)行,直到這個(gè)service 運(yùn)行結(jié)束。另外,我們還可以通過(guò)使用Context.bindService()方法,連接到一個(gè)service 上(如果這個(gè)service 還沒(méi)有運(yùn)行將啟動(dòng)它)。當(dāng)連

12、接到一個(gè)service 之后,我們還可以service 提供的接口與它進(jìn)行通訊。拿媒體播放器這個(gè)例子來(lái)說(shuō),我們還可以進(jìn)行暫停、重播等操作。Service使用步驟如下 1繼承service類(lèi) 2AndroidManifast.xml配置清單文件中節(jié)點(diǎn)里對(duì)服務(wù)進(jìn)行配置 服務(wù)不能自己運(yùn)行,需要通過(guò)Contex.startService()或Contex.bindService()啟動(dòng)服務(wù)通過(guò)startService()方法啟動(dòng)的服務(wù)于調(diào)用者沒(méi)有關(guān)系,即使調(diào)用者關(guān)閉了,服務(wù)仍然運(yùn)行想停止服務(wù)要調(diào)用Context.stopService(),此時(shí)系統(tǒng)會(huì)調(diào)用onDestory(),使用此方法啟動(dòng)時(shí),服務(wù)首

13、次啟動(dòng)系統(tǒng)先調(diào)用服務(wù)的onCreate()-onStart(),如果服務(wù)已經(jīng)啟動(dòng)再次調(diào)用只會(huì)觸發(fā)onStart()方法使用bindService()啟動(dòng)的服務(wù)與調(diào)用者綁定,只要調(diào)用者關(guān)閉服務(wù)就終止,使用此方法啟動(dòng)時(shí),服務(wù)首次啟動(dòng)系統(tǒng)先調(diào)用服務(wù)的onCreate()-onBind(),如果服務(wù)已經(jīng)啟動(dòng)再次調(diào)用不會(huì)再觸發(fā)這2個(gè)方法,調(diào)用者退出時(shí)系統(tǒng)會(huì)調(diào)用服務(wù)的onUnbind()-onDestory(),想主動(dòng)解除綁定可使用Contex.unbindService(),系統(tǒng)依次調(diào)用onUnbind()-onDestory();Content Provider內(nèi)容提供者 :android平臺(tái)提供了C

14、ontent Provider使一個(gè)應(yīng)用程序的指定數(shù)據(jù)集提供給其他應(yīng)用程序。這些數(shù)據(jù)可以存儲(chǔ)在文件系統(tǒng)中、在一個(gè)SQLite數(shù)據(jù)庫(kù)、或以任何其他合理的方式,其他應(yīng)用可以通過(guò)ContentResolver類(lèi)(見(jiàn)ContentProviderAccessApp例子)從該內(nèi)容提供者中獲取或存入數(shù)據(jù).(相當(dāng)于在應(yīng)用外包了一層殼),只有需要在多個(gè)應(yīng)用程序間共享數(shù)據(jù)是才需要內(nèi)容提供者。例如,通訊錄數(shù)據(jù)被多個(gè)應(yīng)用程序使用,且必須存儲(chǔ)在一個(gè)內(nèi)容提供者中它的好處:統(tǒng)一數(shù)據(jù)訪問(wèn)方式。android系統(tǒng)自帶的內(nèi)容提供者(頂級(jí)的表示數(shù)據(jù)庫(kù)名,非頂級(jí)的都是表名)這些內(nèi)容提供者在SDK文檔的vide

15、r Java包中都有介紹。見(jiàn):BrowserCallLogContacts Groups People Phones PhotosImages ThumbnailsMediaStore Albums Artists Audio Genres PlaylistsSettingsVideoCallLog:地址和接收到的電話信息Contact.People.Phones:存儲(chǔ)電話號(hào)碼Setting.System:系統(tǒng)設(shè)置和偏好設(shè)置使用Content Provider對(duì)外共享數(shù)據(jù)的步驟1繼承ContentProvider類(lèi)并根據(jù)需求重寫(xiě)以下方法:public boolean onCreate();/處

16、理初始化操作 /* * 插入數(shù)據(jù)到內(nèi)容提供者(允許其他應(yīng)用向你的應(yīng)用中插入數(shù)據(jù)時(shí)重寫(xiě)) * param uri * param initialValues 插入的數(shù)據(jù) * return */ public Uri insert(Uri uri, ContentValues initialValues); /* * 從內(nèi)容提供者中刪除數(shù)據(jù)(允許其他應(yīng)用刪除你應(yīng)用的數(shù)據(jù)時(shí)重寫(xiě)) * param uri * param selection 條件語(yǔ)句 * param selectionArgs 參數(shù) * return */ public int delete(Uri uri, String selec

17、tion, String selectionArgs); /* * 更新內(nèi)容提供者已存在的數(shù)據(jù)(允許其他應(yīng)用更新你應(yīng)用的數(shù)據(jù)時(shí)重寫(xiě)) * param uri * param values 更新的數(shù)據(jù) * param selection 條件語(yǔ)句 * param selectionArgs 參數(shù) * return */ public int update(Uri uri, ContentValues values, String selection, String selectionArgs); /* * 返回?cái)?shù)據(jù)給調(diào)用者(允許其他應(yīng)用從你的應(yīng)用中獲取數(shù)據(jù)時(shí)重寫(xiě)) * param uri * p

18、aram projection 列名 * param selection 條件語(yǔ)句 * param selectionArgs 參數(shù) * param sortOrder 排序 * return */ public Cursor query(Uri uri, String projection, String selection, String selectionArgs, String sortOrder) ; /* * 用于返回當(dāng)前Uri所代表數(shù)據(jù)的MIME類(lèi)型 * 如果操作的數(shù)據(jù)為集合類(lèi)型(多條數(shù)據(jù)),那么返回的類(lèi)型字符串應(yīng)該為vnd.android.cursor.dir/開(kāi)頭 * 例如要

19、得到所有person記錄的Uri為content:/vider.personprovider/person, *那么返回的MIME類(lèi)型字符串應(yīng)該為vnd.android.cursor.dir/person * 如果操作的數(shù)據(jù)為單一數(shù)據(jù),那么返回的類(lèi)型字符串應(yīng)該為vnd.android.cursor.item/開(kāi)頭 * 例如要得到id為10的person記錄的Uri為content:/vider.personprovider/person/10, *那么返回的MIME類(lèi)型字符串應(yīng)該為vnd.android.cursor.it

20、em/person * param uri */ public String getType(Uri uri)這些方法中的Uri參數(shù),得到后需要進(jìn)行解析然后做對(duì)應(yīng)處理,Uri表示要操作的數(shù)據(jù),包含兩部分信息: 1.需要操作的contentprovider 2.對(duì)contentprovider中的什么數(shù)據(jù)進(jìn)行操作,一個(gè)Uri格式:結(jié)構(gòu)頭:/authorities(域名)/路徑(要操作的數(shù)據(jù),根據(jù)業(yè)務(wù)而定) content:/vider.personprovider/person/10說(shuō)明:contentprovider的結(jié)構(gòu)頭已經(jīng)由android規(guī)定為cont

21、ent:/authorities用于唯一標(biāo)識(shí)這個(gè)contentprovider程序,外部調(diào)用者可以根據(jù)這個(gè)找到他路徑表示我們要操作的數(shù)據(jù),路徑的構(gòu)建根據(jù)業(yè)務(wù)而定.路徑格式如下: 要操作person表行號(hào)為10的記錄,可以這樣構(gòu)建/person/10 要操作person表的所有記錄,可以這樣構(gòu)建/person2在AndroidManifest.xml中使用對(duì)ContentProvider進(jìn)行配置注冊(cè)(內(nèi)容提供者注冊(cè)它自己就像網(wǎng)站注冊(cè)域名),ContentProvider采用authoritie(原意授權(quán),可理解為域名)作為唯一標(biāo)識(shí),方便其他應(yīng)用能找到 .關(guān)于四大基本組件的一個(gè)總結(jié):1 4大組件的

22、注冊(cè)4大基本組件都需要注冊(cè)才能使用,每個(gè)Activity、service、Content Provider內(nèi)容提供者都需要在AndroidManifest文件中進(jìn)行配置AndroidManifest文件中未進(jìn)行聲明的activity、服務(wù)以及內(nèi)容提供者將不為系統(tǒng)所見(jiàn),從而也就不可用,而B(niǎo)roadcastReceive廣播接收者的注冊(cè)分靜態(tài)注冊(cè)(在AndroidManifest文件中進(jìn)行配置)和通過(guò)代碼動(dòng)態(tài)創(chuàng)建并以調(diào)用Context.registerReceiver()的方式注冊(cè)至系統(tǒng)。需要注意的是在AndroidManifest文件中進(jìn)行配置的廣播接收者會(huì)隨系統(tǒng)的啟動(dòng)而一直處于活躍狀態(tài),只要接

23、收到感興趣的廣播就會(huì)觸發(fā)(即使程序未運(yùn)行)AndroidManifest文件中進(jìn)行注冊(cè)格式如下:元素的name 屬性指定了實(shí)現(xiàn)了這個(gè)activity 的Activity 的子類(lèi)。icon 和label 屬性指向了包含展示給用戶的此activity 的圖標(biāo)和標(biāo)簽的資源文件。 元素用于聲明服務(wù) 元素用于聲明廣播接收器 元素用于聲明內(nèi)容提供者2 4大組件的激活 容提供者的激活:當(dāng)接收到ContentResolver 發(fā)出的請(qǐng)求后,內(nèi)容提供者被激活。而其它三種組件activity、服務(wù)和廣播接收器被一種叫做intent 的異步消息所激活 Activity的激活通過(guò)傳遞一個(gè)Intent 對(duì)象至Conte

24、xt.startActivity()或Activity.startActivityForResult()以載入(或指定新工作給)一個(gè)activity。相應(yīng)的activity 可以通過(guò)調(diào)用getIntent() 方法來(lái)查看激活它的intent。如果它期望它所啟動(dòng)的那個(gè)activity 返回一個(gè)結(jié)果,它會(huì)以調(diào)用startActivityForResult()來(lái)取代startActivity()。比如說(shuō),如果它啟動(dòng)了另外一個(gè)Activity 以使用戶挑選一張照片,它也許想知道哪張照片被選中了。結(jié)果將會(huì)被封裝在一個(gè)Intent 對(duì)象中,并傳遞給發(fā)出調(diào)用的activity 的onActivityResu

25、lt() 方法。 服務(wù)的激活可以通過(guò)傳遞一個(gè)Intent 對(duì)象至Context.startService()或Context.bindService()前者Android 調(diào)用服務(wù)的onStart()方法并將Intent 對(duì)象傳遞給它,后者Android 調(diào)用服務(wù)的onBind()方法將這個(gè)Intent 對(duì)象傳遞給它 發(fā)送廣播可以通過(guò)傳遞一個(gè)Intent 對(duì)象至給Context.sendBroadcast() 、Context.sendOrderedBroadcast()或Context.sendStickyBroadcast()Android 會(huì)調(diào)用所有對(duì)此廣播有興趣的廣播接收器的onRec

26、eive()方法,將intent 傳遞給它們3 四大組件的關(guān)閉內(nèi)容提供者僅在響應(yīng)ContentResolver 提出請(qǐng)求的時(shí)候激活。而一個(gè)廣播接收器僅在響應(yīng)廣播信息的時(shí)候激活。所以,沒(méi)有必要去顯式的關(guān)閉這些組件。Activity關(guān)閉:可以通過(guò)調(diào)用它的finish()方法來(lái)關(guān)閉一個(gè)activity服務(wù)關(guān)閉:對(duì)于通過(guò)startService()方法啟動(dòng)的服務(wù)要調(diào)用Context.stopService()方法關(guān)閉服務(wù),使用bindService()方法啟動(dòng)的服務(wù)要調(diào)用Contex.unbindService ()方法關(guān)閉服務(wù)二:四大組件的生命周期介紹生命周期之前,先提一下任務(wù)的概念任務(wù)其實(shí)就是ac

27、tivity 的棧它由一個(gè)或多個(gè)Activity組成的共同完成一個(gè)完整的用戶體驗(yàn), 換句話說(shuō)任務(wù)就是” 應(yīng)用程序” (可以是一個(gè)也可以是多個(gè),比如假設(shè)你想讓用戶看到某個(gè)地方的街道地圖。而已經(jīng)存在一個(gè)具有此功能的activity 了,那么你的activity 所需要做的工作就是把請(qǐng)求信息放到一個(gè)Intent 對(duì)象里面,并把它傳遞給startActivity()。于是地圖瀏覽器就會(huì)顯示那個(gè)地圖。而當(dāng)用戶按下BACK 鍵的時(shí)候,你的activity 又會(huì)再一次的顯示在屏幕上,此時(shí)任務(wù)是由2個(gè)應(yīng)用程序中的相關(guān)activity組成的)棧底的是啟動(dòng)整個(gè)任務(wù)的Activity,棧頂?shù)氖钱?dāng)前運(yùn)行的用戶可以交互

28、的Activity,當(dāng)一個(gè)activity 啟動(dòng)另外一個(gè)的時(shí)候,新的activity 就被壓入棧,并成為當(dāng)前運(yùn)行的activity。而前一個(gè)activity 仍保持在棧之中。當(dāng)用戶按下BACK 鍵的時(shí)候,當(dāng)前activity 出棧,而前一個(gè)恢復(fù)為當(dāng)前運(yùn)行的activity。棧中保存的其實(shí)是對(duì)象,棧中的Activity 永遠(yuǎn)不會(huì)重排,只會(huì)壓入或彈出,所以如果發(fā)生了諸如需要多個(gè)地圖瀏覽器的情況,就會(huì)使得一個(gè)任務(wù)中出現(xiàn)多個(gè)同一Activity 子類(lèi)的實(shí)例同時(shí)存在。任務(wù)中的所有activity 是作為一個(gè)整體進(jìn)行移動(dòng)的。整個(gè)的任務(wù)(即activity 棧)可以移到前臺(tái),或退至后臺(tái)。舉個(gè)例子說(shuō),比如當(dāng)前

29、任務(wù)在棧中存有四個(gè)activity三個(gè)在當(dāng)前activity 之下。當(dāng)用戶按下HOME 鍵的時(shí)候,回到了應(yīng)用程序加載器,然后選擇了一個(gè)新的應(yīng)用程序(也就是一個(gè)新任務(wù))。則當(dāng)前任務(wù)遁入后臺(tái),而新任務(wù)的根activity 顯示出來(lái)。然后,過(guò)了一小會(huì)兒,用戶再次回到了應(yīng)用程序加載器而又選擇了前一個(gè)應(yīng)用程序(上一個(gè)任務(wù))。于是那個(gè)任務(wù),帶著它棧中所有的四個(gè)activity,再一次的到了前臺(tái)。當(dāng)用戶按下BACK 鍵的時(shí)候,屏幕不會(huì)顯示出用戶剛才離開(kāi)的activity(上一個(gè)任務(wù)的根activity)。取而代之,當(dāng)前任務(wù)的棧中最上面的activity 被彈出,而同一任務(wù)中的上一個(gè)activity 顯示了出

30、來(lái)。Activity棧:先進(jìn)先出規(guī)則 Android系統(tǒng)是一個(gè)多任務(wù)(Multi-Task)的操作系統(tǒng),可以在用手機(jī)聽(tīng)音樂(lè)的同時(shí),也執(zhí)行其他多個(gè)程序。每多執(zhí)行一個(gè)應(yīng)用程序,就會(huì)多耗費(fèi)一些系統(tǒng)內(nèi)存,當(dāng)同時(shí)執(zhí)行的程序過(guò)多,或是關(guān)閉的程序沒(méi)有正確釋放掉內(nèi)存,系統(tǒng)就會(huì)覺(jué)得越來(lái)越慢,甚至不穩(wěn)定。為了解決這個(gè)問(wèn)題, Android 引入了一個(gè)新的機(jī)制- 生命周期(Life Cycle)。Android 應(yīng)用程序的生命周期是由Android 框架進(jìn)行管理,而不是由應(yīng)用程序直接控制。通常,每一個(gè)應(yīng)用程序(入口一般會(huì)是一個(gè)Activity 的onCreate 方法),都會(huì)產(chǎn)生一個(gè)進(jìn)程(Process)。當(dāng)系統(tǒng)內(nèi)

31、存即將不足的時(shí)候,會(huì)依照優(yōu)先級(jí)自動(dòng)進(jìn)行進(jìn)程(process)的回收。不管是使用者或開(kāi)發(fā)者, 都無(wú)法確定的應(yīng)用程序何時(shí)會(huì)被回收。所以為了很好的防止數(shù)據(jù)丟失和其他問(wèn)題,了解生命周期很重要。Activity生命周期: 圖3.1activity生命周期圖Activity整個(gè)生命周期的4種狀態(tài)、7個(gè)重要方法和3個(gè)嵌套循環(huán)1四種狀態(tài)1. 活動(dòng)(Active/Running)狀態(tài)當(dāng)Activity運(yùn)行在屏幕前臺(tái)(處于當(dāng)前任務(wù)活動(dòng)棧的最上面),此時(shí)它獲取了焦點(diǎn)能響應(yīng)用戶的操作,屬于運(yùn)行狀態(tài),同一個(gè)時(shí)刻只會(huì)有一個(gè)Activity 處于活動(dòng)(Active)或運(yùn)行(Running)狀態(tài)1. 暫停(Paused)狀態(tài)

32、當(dāng)Activity失去焦點(diǎn)但仍對(duì)用戶可見(jiàn)(如在它之上有另一個(gè)透明的Activity或Toast、AlertDialog等彈出窗口時(shí))它處于暫停狀態(tài)。暫停的Activity仍然是存活狀態(tài)(它保留著所有的狀態(tài)和成員信息并保持和窗口管理器的連接),但是當(dāng)系統(tǒng)內(nèi)存極小時(shí)可以被系統(tǒng)殺掉3.停止(Stopped)狀態(tài)完全被另一個(gè)Activity遮擋時(shí)處于停止?fàn)顟B(tài),它仍然保留著所有的狀態(tài)和成員信息。只是對(duì)用戶不可見(jiàn),當(dāng)其他地方需要內(nèi)存時(shí)它往往被系統(tǒng)殺掉4.非活動(dòng)(Dead)狀態(tài)Activity 尚未被啟動(dòng)、已經(jīng)被手動(dòng)終止,或已經(jīng)被系統(tǒng)回收時(shí)處于非活動(dòng)的狀態(tài),要手動(dòng)終止Activity,可以在程序中調(diào)用fin

33、ish方法。如果是(按根據(jù)內(nèi)存不足時(shí)的回收規(guī)則)被系統(tǒng)回收,可能是因?yàn)閮?nèi)存不足了內(nèi)存不足時(shí),Dalvak 虛擬機(jī)會(huì)根據(jù)其內(nèi)存回收規(guī)則來(lái)回收內(nèi)存:1. 先回收與其他Activity 或Service/Intent Receiver 無(wú)關(guān)的進(jìn)程(即優(yōu)先回收獨(dú)立的Activity)因此建議,我們的一些(耗時(shí))后臺(tái)操作,最好是作成Service的形式2.不可見(jiàn)(處于Stopped狀態(tài)的)Activity3.Service進(jìn)程(除非真的沒(méi)有內(nèi)存可用時(shí)會(huì)被銷(xiāo)毀)4.非活動(dòng)的可見(jiàn)的(Paused狀態(tài)的)Activity5.當(dāng)前正在運(yùn)行(Active/Running狀態(tài)的)Activity27個(gè)重要方法,當(dāng)A

34、ctivity從一種狀態(tài)進(jìn)入另一狀態(tài)時(shí)系統(tǒng)會(huì)自動(dòng)調(diào)用下面相應(yīng)的方法來(lái)通知用戶這種變化當(dāng)Activity第一次被實(shí)例化的時(shí)候系統(tǒng)會(huì)調(diào)用,整個(gè)生命周期只調(diào)用1次這個(gè)方法通常用于初始化設(shè)置: 1、為Activity設(shè)置所要使用的布局文件2、為按鈕綁定監(jiān)聽(tīng)器等靜態(tài)的設(shè)置操作onCreate(Bundle savedInstanceState);當(dāng)Activity可見(jiàn)未獲得用戶焦點(diǎn)不能交互時(shí)系統(tǒng)會(huì)調(diào)用onStart();當(dāng)Activity已經(jīng)停止然后重新被啟動(dòng)時(shí)系統(tǒng)會(huì)調(diào)用onRestart();當(dāng)Activity可見(jiàn)且獲得用戶焦點(diǎn)能交互時(shí)系統(tǒng)會(huì)調(diào)用onResume();當(dāng)系統(tǒng)啟動(dòng)另外一個(gè)新的Activi

35、ty時(shí),在新Activity啟動(dòng)之前被系統(tǒng)調(diào)用保存現(xiàn)有的Activity中的持久數(shù)據(jù)、停止動(dòng)畫(huà)等,這個(gè)實(shí)現(xiàn)方法必須非常快。當(dāng)系統(tǒng)而不是用戶自己出于回收內(nèi)存時(shí),關(guān)閉了activity 之后。用戶會(huì)期望當(dāng)他再次回到這個(gè)activity 的時(shí)候,它仍保持著上次離開(kāi)時(shí)的樣子。此時(shí)用到了onSaveInstanceState(),方法onSaveInstanceState()用來(lái)保存Activity被殺之前的狀態(tài),在onPause()之前被觸發(fā),當(dāng)系統(tǒng)為了節(jié)省內(nèi)存銷(xiāo)毀了Activity(用戶本不想銷(xiāo)毀)時(shí)就需要重寫(xiě)這個(gè)方法了,當(dāng)此Activity再次被實(shí)例化時(shí)會(huì)通過(guò)onCreate(Bundle sav

36、edInstanceState)將已經(jīng)保存的臨時(shí)狀態(tài)數(shù)據(jù)傳入因?yàn)閛nSaveInstanceState()方法不總是被調(diào)用,觸發(fā)條件為(按下HOME鍵,按下電源按鍵關(guān)閉屏幕,橫豎屏切換情況下),你應(yīng)該僅重寫(xiě)onSaveInstanceState()來(lái)記錄activity的臨時(shí)狀態(tài),而不是持久的數(shù)據(jù)。應(yīng)該使用onPause()來(lái)存儲(chǔ)持久數(shù)據(jù)。onPause();當(dāng)Activity被新的Activity完全覆蓋不可見(jiàn)時(shí)被系統(tǒng)調(diào)用onStop();當(dāng)Activity(用戶調(diào)用finish()或系統(tǒng)由于內(nèi)存不足)被系統(tǒng)銷(xiāo)毀殺掉時(shí)系統(tǒng)調(diào)用,(整個(gè)生命周期只調(diào)用1次)用來(lái)釋放onCreate ()方法中創(chuàng)

37、建的資源,如結(jié)束線程等onDestroy();33個(gè)嵌套循環(huán)1.Activity完整的生命周期:從第一次調(diào)用onCreate()開(kāi)始直到調(diào)用onDestroy()結(jié)束2.Activity的可視生命周期:從調(diào)用onStart()到相應(yīng)的調(diào)用onStop()在這兩個(gè)方法之間,可以保持顯示Activity所需要的資源。如在onStart()中注冊(cè)一個(gè)廣播接收者監(jiān)聽(tīng)影響你的UI的改變,在onStop() 中注銷(xiāo)。3.Activity的前臺(tái)生命周期:從調(diào)用onResume()到相應(yīng)的調(diào)用onPause()。舉例說(shuō)明:例1:有3個(gè)Acitivity,分別用One,Two(透明的),Three表示,One是

38、應(yīng)用啟動(dòng)時(shí)的主Activity啟動(dòng)第一個(gè)界面Activity One時(shí),它的次序是onCreate (ONE) - onStart (ONE) - onResume(ONE)點(diǎn)打開(kāi)透明Activity按鈕時(shí),這時(shí)走的次序是onPause(ONE) - onCreate(TWO) - onStart(TWO) - onResume(TWO)再點(diǎn)back回到第一個(gè)界面,Two會(huì)被殺這時(shí)走的次序是onPause(TWO) - onActivityResult(ONE) - onResume(ONE) - onStop(TWO) - onDestroy(TWO)點(diǎn)打開(kāi)全屏Activity按鈕時(shí),這時(shí)走

39、的次序是onPause(ONE) - onCreate(Three) - onStart(Three) - onResume(Three) - onStop(ONE)再點(diǎn)back回到第一個(gè)界面,Three會(huì)被殺這時(shí)走的次序是onPause(Three) - onActivityResult(ONE) - onRestart(ONE) - onStart(ONE)- onResume(ONE) - onStop(Three) - onDestroy(Three)再點(diǎn)back退出應(yīng)用時(shí),它的次序是onPause(ONE) - onStop(ONE) - onDestroy(ONE)例2:橫豎屏切換

40、時(shí)候Activity的生命周期他切換時(shí)具體的生命周期是怎么樣的:1、新建一個(gè)Activity,并把各個(gè)生命周期打印出來(lái)2、運(yùn)行Activity,得到如下信息onCreate-onStart-onResume-3、按crtl+f12切換成橫屏?xí)ronSaveInstanceState-onPause-onStop-onDestroy-onCreate-onStart-onRestoreInstanceState-onResume-4、再按crtl+f12切換成豎屏?xí)r,發(fā)現(xiàn)打印了兩次相同的logonSaveInstanceState-onPause-onStop-onDestroy-onCreate

41、-onStart-onRestoreInstanceState-onResume-onSaveInstanceState-onPause-onStop-onDestroy-onCreate-onStart-onRestoreInstanceState-onResume-5、修改AndroidManifest.xml,把該Activity添加android:configChanges=orientation,執(zhí)行步驟3onSaveInstanceState-onPause-onStop-onDestroy-onCreate-onStart-onRestoreInstanceState-onRes

42、ume-6、再執(zhí)行步驟4,發(fā)現(xiàn)不會(huì)再打印相同信息,但多打印了一行onConfigChangedonSaveInstanceState-onPause-onStop-onDestroy-onCreate-onStart-onRestoreInstanceState-onResume-onConfigurationChanged-7、把步驟5的android:configChanges=orientation 改成 android:configChanges=orientation|keyboardHidden,執(zhí)行步驟3,就只打印onConfigChangedonConfigurationChanged-8、執(zhí)行步驟4onConfigurationChanged-onConfigurationChanged-總結(jié):1、不設(shè)置Activity的android:configChanges時(shí),切屏?xí)匦抡{(diào)用各個(gè)生命周期,切橫屏?xí)r會(huì)執(zhí)行一次,切豎屏?xí)r會(huì)執(zhí)行兩次2、設(shè)置Activity的android:configChang

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論