Activity生命周期
(一)簡介
onCreate()
在系統(tǒng)創(chuàng)建活動時觸發(fā)割卖;
onStart()
作為onCreate()退出時报嵌,活動進入開始狀態(tài)开皿,并且activity變得對用戶可見染服;
onResume()
當(dāng)一個活動和用戶發(fā)生交互的時候,觸發(fā)該方法飘弧。此時,activity位于activity堆棧的頂部砚著,并捕獲所有用戶輸入次伶。應(yīng)用程序的大多數(shù)核心功能是在此方法中實現(xiàn)的。
onPause()
當(dāng)活動失去焦點并進入暫停狀態(tài)時稽穆,系統(tǒng)會調(diào)用冠王。例如當(dāng)用戶點擊“后退”或“最近”按鈕時,會出現(xiàn)此狀態(tài)舌镶。
當(dāng)系統(tǒng)調(diào)用此方法時版确,通常表示用戶正在離開此activity(文檔中表示為partially visable,也就是部分可見)乎折,并將很快進入“已停止”或“已恢復(fù)”狀態(tài)绒疗。在一些場景下會需要調(diào)用此方法:示出(也就是該activity不被顯示在屏幕上時)導(dǎo)航地圖屏幕或媒體播放器播放的活動。即使這些活動失去焦點骂澄,用戶也希望它們的UI繼續(xù)更新吓蘑。
你不應(yīng)該在此方法中保存應(yīng)用程序或用戶數(shù)據(jù),進行網(wǎng)絡(luò)通話坟冲,或執(zhí)行數(shù)據(jù)庫事務(wù)磨镶。
一旦onPause()完成執(zhí)行,下一個回調(diào)是onStop()或onResume()健提,視activity進入暫停狀態(tài)后發(fā)生的情況而定琳猫。
onStop()
當(dāng)活動不再對用戶可見時調(diào)用。
此方法被調(diào)用的情況有:activity正在被破壞私痹,新activity正在開始脐嫂,或現(xiàn)有activity正在進入恢復(fù)狀態(tài)并且覆蓋已停止的活動。
如果內(nèi)存緊張紊遵,系統(tǒng)會直接結(jié)束這個活動账千,而不會觸發(fā) onStop 方法。 所以保存狀態(tài)信息是應(yīng)該在onPause時做暗膜,而不是onStop時做匀奏。
onRestart()
當(dāng)處于“已停止”(Stop)狀態(tài)的activity即將重新啟動時,系統(tǒng)將調(diào)用此方法学搜。此回調(diào)始終緊跟著onStart()后發(fā)生娃善。
onDestory()
此方法在銷毀activity之前被調(diào)用论衍。通常實現(xiàn)以確保在activity或包含它的進程被銷毀時釋放所有活動的資源。
==額外:==
onSaveInstanceState() :系統(tǒng)調(diào)用該方法聚磺,允許活動保存之前的狀態(tài)饲齐,比如說在一串字符串中的光標(biāo)所處的位置等。
通常情況下,開發(fā)者不需要重寫覆蓋該方法,在默認的實現(xiàn)中蓝谨,已經(jīng)提供了自動保存活動所涉及到的用戶界面組件的所有狀態(tài)信息。
(二)Activity狀態(tài)
一般認為Activity有以下四種狀態(tài):
活動的:當(dāng)一個Activity在棧頂滥搭,它是可視的、有焦點捣鲸、可接受用戶輸入的瑟匆。Android試圖盡最大可能保持它活動狀態(tài),殺死其它Activity來確保當(dāng)前活動Activity有足夠的資源可使用栽惶。當(dāng)另外一個Activity被激活愁溜,這個將會被暫停。
暫停:在很多情況下外厂,你的Activity可視但是它沒有焦點冕象,換句話說它被暫停了。有可能原因是一個透明或者非全屏的Activity被激活汁蝶。
當(dāng)被暫停渐扮,一個Activity仍會當(dāng)成活動狀態(tài),只不過是不可以接受用戶輸入掖棉。在極特殊的情況下墓律,Android將會殺死一個暫停的Activity來為活動的Activity提供充足的資源。當(dāng)一個Activity變?yōu)橥耆[藏幔亥,它將會變成停止耻讽。停止:當(dāng)一個Activity不是可視的,它“停止”了帕棉。這個Activity將仍然在內(nèi)存中保存它所有的狀態(tài)和會員信息针肥。盡管如此笤昨,當(dāng)其它地方需要內(nèi)存時祖驱,它將是最有可能被釋放資源的。當(dāng)一個Activity停止后瞒窒,一個很重要的步驟是要保存數(shù)據(jù)和當(dāng)前UI狀態(tài)。一旦一個Activity退出或關(guān)閉了乡洼,它將變?yōu)榇脿顟B(tài)崇裁。
待用: 在一個Activity被殺死后和被裝載前匕坯,它是待用狀態(tài)的。待用Acitivity被移除Activity棧拔稳,并且需要在顯示和可用之前重新啟動它葛峻。
(三)后臺堆棧模型
- 當(dāng)前活動開始另一個活動時,新活動將被推到堆棧頂部并獲得焦點巴比。之前的活動仍在堆棧中术奖,但已停止。當(dāng)活動停止時轻绞,系統(tǒng)將保留其用戶界面的當(dāng)前狀態(tài)采记。當(dāng)用戶按下“ 返回” 按鈕時,當(dāng)前活動將從堆棧頂部彈出(活動被銷毀)政勃,之前的活動將恢復(fù)(其UI的先前狀態(tài)將恢復(fù))唧龄。堆棧中的活動永遠不會重新排列,只能在當(dāng)前活動啟動時從堆棧中推送并彈出到堆棧中奸远,并在用戶使用Back退出時彈出按鈕既棺。因此,后堆棧作為“后進先出”對象結(jié)構(gòu)操作懒叛。圖1顯示了這種行為丸冕,時間軸顯示了活動之間的進度以及每個時間點的當(dāng)前后棧。
注意:可以在后臺同時保存多個任務(wù)薛窥。但是晨仑,如果用戶同時運行許多后臺任務(wù),系統(tǒng)可能會開始銷毀后臺活動以恢復(fù)內(nèi)存拆檬,從而導(dǎo)致活動狀態(tài)丟失洪己。
- 由于后備堆棧中的活動永遠不會重新排列,如果您的應(yīng)用程序允許用戶從多個活動啟動特定活動竟贯,則會創(chuàng)建該活動的新實例并將其推送到堆棧(而不是帶來任何先前的活動實例)到頂部)答捕。因此,應(yīng)用程序中的一個活動可能會被多次實例化(甚至來自不同的任務(wù))屑那,因此拱镐,如果用戶使用“ 后退”按鈕向后導(dǎo)航,則活動的每個實例都按順序顯示被打開(每個都有自己的UI狀態(tài))持际。但是沃琅,如果您不希望多次實例化活動,則可以修改此行為蜘欲。有關(guān)如何執(zhí)行此操作將在后面的“ ==管理任務(wù)==”一節(jié)中討論益眉。
(四)管理任務(wù)
定義啟動模式
啟動模式允許您定義活動的新實例與當(dāng)前任務(wù)堆棧的關(guān)聯(lián)方式。您可以通過兩種方式定義不同的啟動模式:使用清單文件或使用Intent標(biāo)志。(清單文件Manifest.xml優(yōu)先級高一些)
使用清單文件定義啟動模式:
在清單文件中聲明活動時郭脂,可以使用<activity> 元素的launchMode屬性指定活動應(yīng)如何與任務(wù)關(guān)聯(lián)年碘。其有四種不同的啟動模式:
- "standard" (默認模式):系統(tǒng)在啟動它的任務(wù)中創(chuàng)建活動的新實例,并將意圖路由到該實例展鸡∮煨疲活動可以多次實例化,每個實例可以屬于不同的任務(wù)莹弊,一個任務(wù)可以有多個實例涤久。
- "singleTop":若activity的實例已存在于當(dāng)前任務(wù)堆棧頂部(也就是當(dāng)前活動),則系統(tǒng)通過調(diào)用onNewIntent()方法將Intent路由到該實例忍弛,而不是創(chuàng)建activity的新實例响迂;反之則和standard模式一樣。
- "singleTask":系統(tǒng)創(chuàng)建新任務(wù)堆棧并將activity放在其根目錄下實例化剧罩。但如果activity的實例已存在于單獨的任務(wù)堆棧中栓拜,則系統(tǒng)會通過調(diào)用onNewIntent()路由到現(xiàn)有實例,而不創(chuàng)建新的惠昔。一次只能存在一個該activity實例幕与。
注意:雖然activity在新任務(wù)中啟動,但“后退”按鈕仍會將用戶返回到上一個activity镇防。
- "singleInstance":與上一個類似啦鸣,區(qū)別在于:系統(tǒng)不啟動任何其他活動納入控股實例的任務(wù)±囱酰活動始終是其任務(wù)的唯一成員; 任何由此開始的活動都在一個單獨的任務(wù)中打開诫给。
實例
- 假設(shè)任務(wù)的后臺堆棧由根活動A組成,其中活動B啦扬,C和D位于頂部(堆棧為ABCD; D位于頂部)中狂。意圖到達類型D的活動。如果D具有默認"standard"啟動模式扑毡,則啟動該類的新實例并且堆棧變?yōu)锳BCDD胃榕。但是,如果D的啟動模式是"singleTop"瞄摊,D的現(xiàn)有實例接收意圖onNewIntent()勋又,因為它位于堆棧的頂部 - 堆棧仍然是ABCD。但是换帜,如果意圖到達類型B的活動楔壤,則將新的B實例添加到堆棧中,即使其啟動模式為"singleTop"惯驼。
-
Android瀏覽器應(yīng)用程序聲明Web瀏覽器活動應(yīng)始終在其自己的任務(wù)中打開 - 通過singleTask在<activity>元素中指定啟動模式蹲嚣。這意味著递瑰,如果您的應(yīng)用發(fā)出打開Android瀏覽器的意圖,則其活動不會與您的應(yīng)用放在同一任務(wù)中端铛。相反泣矛,要么為瀏覽器啟動新任務(wù)疲眷,要么如果瀏覽器已經(jīng)在后臺運行任務(wù)禾蚕,則該任務(wù)將被提前處理新意圖。
無論活動是在新任務(wù)中啟動還是在與啟動它的活動相同的任務(wù)中啟動狂丝,“ 返回”按鈕始終會將用戶帶到上一個活動换淆。但是,如果啟動指定singleTask啟動模式的活動几颜,則如果后臺任務(wù)中存在該活動的實例倍试,則將整個任務(wù)帶到前臺。此時蛋哭,后端堆椣叵埃現(xiàn)在包括在堆棧頂部提出的任務(wù)中的所有活動。上圖說明了這種情況谆趾。
使用Intent標(biāo)志定義啟動模式
啟動活動時躁愿,您可以通過在傳遞到的intent中包含標(biāo)志來修改活動與其任務(wù)的默認關(guān)聯(lián)。您可以用來修改默認行為的標(biāo)志是:
- FLAG_ACTIVITY_NEW_TASK:與singleTask相同沪蓬。
- FLAG_ACTIVITY_SINGLE_TOP:與singleTop相同彤钟。
- FLAG_ACTIVITY_CLEAR_TOP:如果正在啟動的活動已在當(dāng)前任務(wù)中運行,則不會啟動該活動的新實例跷叉,而是銷毀其上的所有其他活動逸雹,并將此意圖傳遞給活動的恢復(fù)實例(現(xiàn)在在頂部的)。launchMode沒有此值云挟。FLAG_ACTIVITY_CLEAR_TOP最常與 FLAG_ACTIVITY_NEW_TASK共同使用梆砸。當(dāng)一起使用時,這些標(biāo)志是一種在另一個任務(wù)中定位現(xiàn)有活動并將其置于可以響應(yīng)意圖的位置的方法园欣。
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
啟動模式的區(qū)別
啟動模式的介紹:堆棧與啟動模式
四種加載模式的區(qū)別:
所屬task的區(qū)別
一般情況下帖世,“standard”和”singleTop”的activity的目標(biāo)task,和收到的Intent的發(fā)送者在同一個task內(nèi)俊庇,就相當(dāng)于誰調(diào)用它狮暑,它就跟誰在同一個Task中。
除非Intent包括參數(shù)FLAG_ACTIVITY_NEW_TASK辉饱。如果提供了FLAG_ACTIVITY_NEW_TASK參數(shù)搬男,會啟動到別的task里。
“singleTask”和”singleInstance” 總是把要啟動的activity作為一個task的根元素彭沼,他們不會被啟動到一個其他task里缔逛。是否允許多個實例
“standard”和”singleTop”可以被實例化多次,并且是可以存在于不同的task中;這種實例化時一個task可以包括一個activity的多個實例褐奴;
“singleTask”和”singleInstance”則限制只生成一個實例按脚,并且是task的根元素。
singleTop 要求如果創(chuàng)建intent的時候棧頂已經(jīng)有要創(chuàng)建的Activity的實例敦冬,則將intent發(fā)送給該實例辅搬,而不創(chuàng)建新的實例。是否允許其它activity存在于本task內(nèi)
“singleInstance”獨占一個task脖旱,其它activity不能存在那個task里堪遂;
如果它啟動了一個新的activity,不管新的activity的launch mode 如何萌庆,新的activity都將會到別的task里運行(如同加了FLAG_ACTIVITY_NEW_TASK參數(shù))溶褪。
而另外三種模式,則可以和其它activity共存践险。是否每次都生成新實例
“standard”對于每一個啟動Intent都會生成一個activity的新實例猿妈;
“singleTop”的activity如果在task的棧頂?shù)脑挘瑒t不生成新的該activity的實例巍虫,直接使用棧頂?shù)膶嵗碓颍駝t,生成該activity的實例垫言。
比如:
現(xiàn)在task棧元素為A-B-C-D(D在棧頂)贰剥,這時候給D發(fā)一個啟動intent,如果D是 “standard”的筷频,則生成D的一個新實例蚌成,棧變?yōu)锳-B-C-D-D。
如果D是singleTop的話凛捏,則不會生產(chǎn)D的新實例担忧,棧狀態(tài)仍為A-B-C-D
如果這時候給B發(fā)Intent的話,不管B的launchmode是”standard” 還是 “singleTop” 坯癣,都會生成B的新實例瓶盛,棧狀態(tài)變?yōu)锳-B-C-D-B。
“singleInstance”是其所在棧的唯一activity示罗,它會每次都被重用惩猫。
“singleTask” 如果在棧頂,則接受intent蚜点,否則轧房,該intent會被丟棄,但是該task仍會回到前臺绍绘。 當(dāng)已經(jīng)存在的activity實例處理新的intent時候奶镶,會調(diào)用onNewIntent()方法迟赃,如果收到intent生成一個activity實例,那么用戶可以通過back鍵回到上一個狀態(tài)厂镇;如果是已經(jīng)存在的一個activity來處理這個intent的話纤壁,用戶不能通過按back鍵返回到這之前的狀態(tài)。
(五)處理activity狀態(tài)更改
發(fā)生配置更改
有許多事件可以觸發(fā)配置更改捺信。最突出的例子是屏幕縱向和橫向之間的變化酌媒。其他情況包括更改語言或輸入設(shè)備。
當(dāng)發(fā)生配置更改時残黑,將銷毀并重新創(chuàng)建activity馍佑。原來的activity實例對象的onPause()斋否、onStop()和onDestory()方法將被觸發(fā)梨水。而activity的一個新實例將被創(chuàng)建(也就是onCreate()、onStart()和onResume()方法會被觸發(fā))茵臭。
可以使用ViewModel,onSaveInstanceState()方法和持久本地存儲的組合來保持activity在配置更改中的UI狀態(tài)疫诽。這里需要根據(jù)App情況進行選擇。
activity或?qū)υ捒虺霈F(xiàn)在前臺(foreground)
這里有兩種情況:
activity的焦點被部分覆蓋:系統(tǒng)會調(diào)用onPause()方法旦委,使activity進入暫停狀態(tài)奇徒,當(dāng)被覆蓋的activity重新獲得焦點時,會調(diào)用onResume()方法缨硝。
前臺出現(xiàn)新activity或?qū)υ捒蚰Ω疲P(guān)注焦點并完全覆蓋正在進行的activity:當(dāng)前activity進入“已停止”狀態(tài),系統(tǒng)快速連續(xù)調(diào)用onPause()和onStop()查辩。當(dāng)覆蓋活動的同一實例回來到前臺時胖笛,系統(tǒng)調(diào)用onRestart(), onStart()以及 onResume()對活動宜岛。如果它是覆蓋活動的新實例长踊,則系統(tǒng)不會調(diào)用onRestart(),只調(diào)用 onStart()和 onResume()萍倡。
注意:當(dāng)用戶點擊“概覽”或“主頁”按鈕時身弊,系統(tǒng)的行為就像當(dāng)前活動已完全覆蓋一樣。
用戶點擊后退按鈕(Back button)
如果activity是在前臺列敲,而用戶點擊后退按鈕(回到桌面或主頁面)阱佛,該activity通過調(diào)用onPause()、onStop()和onDestory()方法戴而。除了被銷毀之外凑术,activity也從后臺堆棧中移除。
==要注意的是:==默認情況下填硕,onSaveInstanceState()在這種情況下不會觸發(fā)麦萤。但可以在這種情況下覆蓋該****onBackPressed()以實現(xiàn)某些自定義行為鹿鳖,例如“確認退出?”對話框。
系統(tǒng)會殺死應(yīng)用程序進程
如果應(yīng)用程序在后臺并且系統(tǒng)需要為前臺應(yīng)用程序釋放額外的內(nèi)存壮莹,則系統(tǒng)可以終止后臺應(yīng)用程序以釋放更多內(nèi)存翅帜。
==補充==:onSaveInstanceState()被觸發(fā)的條件
- 背景:用戶期望活動的UI狀態(tài)在整個配置更改期間保持不變,例如旋轉(zhuǎn)或切換到多窗口模式命满。但是涝滴,當(dāng)發(fā)生此類配置更改時,系統(tǒng)會默認銷毀活動胶台,從而消除存儲在活動實例中的任何UI狀態(tài)歼疮。同樣,用戶希望UI狀態(tài)保持不變诈唬,如果他們暫時從您的應(yīng)用切換到其他應(yīng)用韩脏,然后稍后再回到您的應(yīng)用。但是铸磅,當(dāng)用戶離開并且您的活動停止時赡矢,系統(tǒng)可能會破壞您的應(yīng)用程序的進程。
- 解決辦法:如果您的UI數(shù)據(jù)簡單而輕量級阅仔,例如原始數(shù)據(jù)類型或簡單對象(如String)吹散,則可以單獨使用onSaveInstanceState()來保持UI狀態(tài)跨越配置更改和系統(tǒng)啟動的進程死亡。但是八酒,在大多數(shù)情況下空民,您應(yīng)該使用ViewModel和onSaveInstanceState()(如 保存UI狀態(tài)中所述),因為onSaveInstanceState()會導(dǎo)致序列化/反序列化成本羞迷。
-
當(dāng)您的活動開始停止時界轩,系統(tǒng)會調(diào)用該 onSaveInstanceState() 方法,以便您的活動可以將狀態(tài)信息保存到實例狀態(tài)包闭树。此方法的默認實現(xiàn)保存有關(guān)活動視圖層次結(jié)構(gòu)狀態(tài)的瞬態(tài)信息耸棒,例如EditText窗口小部件中的文本或窗口小部件的滾動位置 ListView。
要為活動保存其他實例狀態(tài)信息报辱,必須覆蓋 onSaveInstanceState() 并將鍵值對添加到在Bundle活動意外銷毀時保存的對象与殃。如果重寫onSaveInstanceState(),則必須調(diào)用超類實現(xiàn)碍现,如果希望默認實現(xiàn)保存視圖層次結(jié)構(gòu)的狀態(tài)幅疼。例如:
static final String STATE_SCORE = “playerScore” ;
static final String STATE_LEVEL = “playerLevel” ;
@Override
public void onSaveInstanceState (Bundle savedInstanceState ){
//保存用戶當(dāng)前的游戲狀態(tài)
savedInstanceState.putInt (STATE_SCORE ,currentScore );
savedInstanceState.putInt (STATE_LEVEL 昼接,currentLevel );
//始終調(diào)用超類爽篷,以便保存視圖層次結(jié)構(gòu)狀態(tài)
super.onSaveInstanceState (savedInstanceState );
}
注意: 當(dāng)用戶顯式關(guān)閉活動時或當(dāng)finish()被調(diào)用時,onSaveInstanceState()不會被回調(diào)
要保存持久性數(shù)據(jù)(例如用戶首選項或數(shù)據(jù)庫的數(shù)據(jù))慢睡,您應(yīng)該在活動位于前臺時采取適當(dāng)?shù)臋C會逐工。如果沒有這樣的機會铡溪,您應(yīng)該在onStop()方法期間保存這些數(shù)據(jù) 。
- 使用onRestoreInstanceState(Bundle saveInstanceState)方法來還原已保存的狀態(tài)泪喊。(你當(dāng)然也可以在onCreate()中還原已保存的狀態(tài)棕硫,但需要額外判斷是否是銷毀后重新創(chuàng)建此Activity,也就是要判斷onCreate(Bundle savedInstanceState)中的savedInstanceState!=null)
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
currentScore = savedInstanceState.getInt(STATE_SCORE);
currentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
(六) Activity生命周期交互
多個Activity之間切換時的狀態(tài)變化
- 情景一:當(dāng)打開一個app袒啼,進入MainActivity時哈扮,會依次調(diào)用onCreate()、onStart()和onResume()這三個方法蚓再。然后當(dāng)用戶點擊某個按鈕進入到另一個Activity時(這里稱之為second_Activity)滑肉,首先MainActivity會調(diào)用onPause()方法進入“已暫停”狀態(tài)摘仅,接著是second_Activity開始依次調(diào)用onCreate()靶庙、onStart()和onResume(),當(dāng)second_Activity進入到“可見”狀態(tài)時实檀,MainActivity就會調(diào)用onStop()方法惶洲。至此,從一個activity跳轉(zhuǎn)到另一個activity的狀態(tài)變化就結(jié)束了膳犹。
- 情景二:接著上述,當(dāng)在second_Activity中點擊“回退”時签则,該activity會被暫停须床,也就是調(diào)用onPause()方法,然后前一個activity渐裂,也就是MainActivity會依次調(diào)用onRestart()豺旬、onStart()和onResume()方法來重新啟動(當(dāng)activity進入Stopped狀態(tài)時,若要跳到Started狀態(tài)柒凉,要先執(zhí)行onRestart()方法族阅,再執(zhí)行onStart()方法)。而secondActivity接著會調(diào)用onStop()和onDestory()方法膝捞,這樣坦刀,second_Activity就會被徹底銷毀。
疑問:在打開新的Activity時蔬咬,為什么不執(zhí)行當(dāng)前activity的onPause()和onStop()方法鲤遥,而是將二者分別在要跳轉(zhuǎn)的activity的三個方法執(zhí)行前后調(diào)用?
答案:onPause()方法一般用于關(guān)閉當(dāng)前Activity的視頻音頻林艘,或者其他可能妨礙到新的Activity的功能(比如接電話等)盖奈。還可以在跳轉(zhuǎn)到新的Activity前保存當(dāng)前Activity的一些狀態(tài)信息等。而在第二個Activity完全加載之后才執(zhí)行原Activity的onStop()方法狐援,這個設(shè)計主要是為了防止當(dāng)?shù)诙€Activity在加載時出錯出現(xiàn)閃退等異常時钢坦,第一個Activity還能夠顯示在屏幕上究孕,而不是“不可見狀態(tài)”。所以說這是一種考慮了很多情況的設(shè)計爹凹。
橫豎屏切換時的狀態(tài)變化
橫豎屏切換時蚊俺,系統(tǒng)會在當(dāng)前Activity依次執(zhí)行onPause()、onStop()和onDestory()逛万,然后再重新創(chuàng)建泳猬。若想要在切換前后有一致的UI狀態(tài),就需要重載onSaveInstanceState(Bundle outState)方法來將信息保存進outState中宇植,然后在onRestoreInstanceState中還原得封。
生命周期應(yīng)用場景
媒體播放器播放時跳轉(zhuǎn)到其他Activity
假如當(dāng)前Activity在播放著音樂,突然一個電話過來指郁,那么用戶肯定是想當(dāng)前音樂停止然后切換到電話界面忙上,當(dāng)電話結(jié)束后回退到原來界面時,繼續(xù)從剛才的地方播放音樂闲坎。根據(jù)第一條中的情景二疫粥,我們知道此時需要分別在onPause()和onResume()方法中實現(xiàn)一些操作。
- 在onPause()方法中腰懂,判斷播放器在播放的話梗逮,就暫停(mediaPlayer.pause()),并且記錄下當(dāng)前的播放位置(int position=mediaPlayer.getCurrentPosition())
- 而在onResume()方法中绣溜,則需要在position!=0的情況下慷彤,將音樂調(diào)整到position,然后start怖喻。(mediaPlayer.seekTo(position);mediaPlayer.start())底哗。
- 其實還應(yīng)該在onDestroy中釋放掉音樂組件,以免內(nèi)存泄漏锚沸。
Activity啟動的另一種方式:匿名啟動
如下所示跋选,在Manifest.xml文件中,我們可以在<intent-filter>中插入<action>b并添加屬性android:name哗蜈,這樣別的Activity就可以通過這個名字來start此Activity前标,而不是通過Activity真實的類名(在調(diào)用其他App的界面時會使用到,自己的App內(nèi)部沒必要用這種方式)恬叹。
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="jieko" /> //這里可以為此Activity生成自定義的名字
//category指定Activity啟動的環(huán)境
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
//調(diào)用方式:
Intent intent = new Intent();
intent.setAction("jieko");
startActivity(intent);
還可以通過上面的“調(diào)用方法”調(diào)用一些系統(tǒng)內(nèi)置的一些應(yīng)用候生,比如瀏覽器、圖庫绽昼、相機唯鸭、短信、電話等等硅确。示例如下:
//調(diào)用瀏覽器
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW); //Intent中內(nèi)置有一些常量目溉,用來調(diào)用系統(tǒng)app
Uri uri = Uri.parse("...");
intent.setData(uri);
startActivity(intent);