編輯:關於Android編程
Activity的生命周期與工作模式 Activity調用棧管理開篇,我們陳述一下Activity,Activity是整個應用用戶交互的核心組件,了解Activity的工作模式,生命周期和管理方式,是了解Android的基礎,本節主講
Activity作為四大組建出現平率最高的組件,我們在哪裡都能看到他,就讓我們一起先來了解一下他的生命周期
Activity是用戶交互的第一接口,他提供了一個用戶完成指令的窗口,當開發者創建Activity之後,通過調用setContentView來指定一個窗口界面,並以此為基礎,提供給用戶交互的接口,系統采用Activity棧的方式來管理Activity
Activity/RunningActivity一個最大的特點就是擁有多種形態,他可以在多種形態中自由切換,以此來控制自己的生命周期
Paused這個時候,Activity處於Activity棧的最頂層,可見,並與用戶進行交互
StoppedActivity失去焦點,被一個新的非全屏的Activity或者一個透明的Activity放置在棧頂時,Activity就轉換成了qaused形態,他是去了與用戶交互的能力,所有狀態信息,成員變量都還保留著,只有在系統內存極地的情況下,才會被系統回收
Killed如果一個Activity被另一個Activity完全覆蓋,那麼Activity就會進入stop形態,此時他不在可見,但依然保留著所有的狀態和成員變量
當Activity被系統回收或者Activity從來沒有創建過,Activity就處於killed狀態,
由此可見,用戶的不同操作,會讓Activity進入四種不同的狀態,而開發者,只能控制其生,卻不能控制其死
Google給了我們一張圖來表示Activity的生命周期,他希望Activity能被開發者所控制,而不是一匹脫缰的野馬
開發者必然不必實現所有的生命周期方法,但是必須知道每一個生命周期的含義,可以讓我們更好的掌控Activity,讓他能完成你所期望的效果
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onRestart() {
super.onRestart();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
onCreate中創建基本的UI元素 onPause和onStop:清除Acvtivity的資源,避免浪費 onDestroy:因為引用會在Activity銷毀的時候銷毀,而線程不會,所以清除開啟的線程在系統調用onCreate方法之後,就會馬上調用onStart,然後繼續調用onResume來進圖運行狀態,最後都會停在onResume狀態,完成啟動,系統會調用onDestroy來結束一個Activity的生命周期讓他毀掉kill狀態
以上就是一個Activity的啟動和銷毀的過程
onPause:釋放系統資源, onResume:需要重新初始化onPause釋放的資源當棧頂的Activity部分不可見的時候,就會倒置Activity進入onPause
棧頂的Activity部分不可見的時候,實際上後續會有兩種可能,從部分不可見到可見,也就是恢復過程,從部分不可見到完全不可見,也就是停止過程,系統在當前Activity不可見的時候調用onPause
最後我們來看看Activity是如何重新創建的,如果你的系統長時間處於stop的狀態,而此時系統需要更多的內存或者系統內存比較緊張的時候,系統就會回收你的Activity,而系統為了補償你,會將你的Activity狀態通過onRestoreInstanceState()方法保存到Bundle中去,當然你也可以額外增加鍵值對去保存這些狀態,當你重新需要創建這個Activity的時候,保存的Bundle對象就會傳遞到Activity的onRestoreInstanceState()方法中去與onCreate方法中去,這也是onCreate的重要參數——saveInstanceState的來源
不過這裡要注意的一點就是savedInstanceState方法並不是每次當Activity離開前台就會調用,如果用戶使用finish方法結束,則不會調用,而且Android系統已經默認實現了控件的緩存狀態,一次來減少開發者需要實現的緩存邏輯
一個Android應用程序功能通常會被拆分為多個Activity,而各個Activity之間通過Intcnt進行連接,而Android系統,通過棧結構來保存整個App的Activity,棧底的元素是整個任務棧的發起者。一個合理的任務調度棧不僅是性能的保證, 更是提供性能的基礎。
當一個App啟動時,如果當前環境中不存在該App的任務棧,那麼系統就會創建一個任務棧,這個app所啟動的Activity都將在這個任務棧中被管理,這個棧也被稱為Task,即表示若干個acnVity的集合,他們組合在一起形成一個Task。另外,需要特別注意的是,一個Task中的ActiVity可以來自不同的App,同一個App的Acnvity也可能不在一個Task中。
關於棧結構,相信大家都不會太陌生一一後進先出(lastin First out)的線性表。 根據Activity在當前棧結構中的位置,來決定該Acavity的狀態。先來看看正常情況下的android任務棧,當一個Activity啟動了另一個Activity的時候,新啟動的Acnvity就會置於任務棧的頂
端, 並處於活動狀態,而啟動它的Activity雖然功成身退,但依然保留在任務棧中, 處於停止狀態,當用戶按下返回鍵或者調用finish()方法時,系統會移除頂部Activity,讓後面的Acnvity恢復活動狀態。 當然,世界不可能一直這麼“和諧”,可以給Activity設置一些“特權’,來打
破這種“和諧”的模式。這種特權,就是通過在 AndroidMainifest 文件中的屬性android:1aunchMode來設置或者是通過intent的flag來設置的。
standard singleTop singleTask singleInstance下面我們來看看特權,Android開發者可以在AndroidManifest文件中一共設計了四種啟動模式
默認的啟動模式,如果不指定Activity的啟動模式,則使用這種模式來啟動Activity,每次點擊standard模式創建Activity之後,都會創建新的MainActivity覆蓋在原有的Activity上,如圖:
如果指定Activity的啟動方式為singletop,那麼在啟動的時候,系統會判斷當前棧頂Activity是不是要啟動的那個,如果是則不創建新的Activity,如果不是則創建新的Activity,這種模式通常適用於接收到消息後顯示的界面,列入QQ接收到消息後彈出Activity,如果一次來10條,總不能彈10次吧,這種啟動模式的如圖
這種啟動模式雖然不能創建新的實例,但是系統任然會在Activity啟動的時候調用onNewIntent()方法,舉例子,如果當前任務棧中有ABC三個Activity,而C的啟動模式是singleTZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcKOsxMfDtNXiuPbKsbry1NnG9LavQ6OsxMfDtM+1zbO+zbK7u+HIpbS0vahDtcTKtcD9wcujrLb4yse74bX308NDtcRvbk5ld0ludGVudLe9t6ijrLWxx7DIzs7x1bvSwMi7ysdBQkPI/bj2QWN0aXZpdHk8L3A+DQo8L2Jsb2NrcXVvdGU+DQo8aDMgaWQ9"3singletask">3.singleTask
singleTask模式和singleTop模式有點類似,只不過singleTop是檢測棧頂元素是否需要啟動的Activity,而singleTask是檢測整個Activity棧中是否存在當前啟動的Activity,如果存在,就將他置於棧頂,並且將以上的activity全部銷毀,不過這裡也是指在同一個APP中啟動整個singleTask的Activity,如果是其他的程序以singleTask模式來啟動整個Activity,那麼他將創建一個新的任務棧,不過這裡有一點需要注意的是,如果啟動的模式為singleTask的activity已經在後台的一個棧中,那麼啟動後,後台的一個任務棧將一起被切換到前台,,借助官網的一張圖我們可能更好的理解
當Activity2啟動ActivityY的時候(啟動模式為singleTask),他所在的task被切換到前台,且按返回鍵返回的時候,也會先返回ActivityY所在Task的Activity,這一點比較難理解,大家根據圖去研究一下
可以發現,使用這個模式創建的AcnVity不是在新的任務棧中被打開,就是將已打開的Activity換到前台, 所以這種啟動模式通常可以用來退出整個應用,將主Acnvity設為singlelask模式,然後在要退出的AcnVity中轉到主AcnVity,從而將主AcnVity之上的AcnVity全部銷毀,然後重寫主ActlVity的onNewIntent方法 在方法中加上一句finish,將最後一個Activity結束掉。
4.singleInstance
singieInstance這種啟動模式和使用的浏覽器工作原理類似。在多個程序中訪問浏覽器時,如果當前浏覽器沒有打開則打開浏覽器, 否則會在當前打開的浏覽器中訪問. 申明為singleInstance的Activity會出現在一個新的任務棧中而且該任務棧中只存在這一個Activity,舉個例子來說,如果應用A的任務棧中創建了MainActivity實例,且啟動模式為singleInstance,如果應用B也要激活MainActivity 則不需要創建,兩個應用共享該Activity實例,這種啟動模式常用於需要與程序分離的界面: 如在setupWizard中調用緊急呼叫,就是使用這種啟
動模式關於singletop邵p和singleInstance這兩種啟動模式還有一點需要特殊說明: 如果在一個singleTop或者singleInstance的Activity中通過startActivityForResultO方法來啟動另一個ActivityB, 那麼系統將直接返回Activity_RESULT_CANCELED而不會再去等待返回。 這是由於系統在framework層做了對這兩種啟動模式的限制, 因為Android開發者認為,不同的Task中,默認是不能傳遞數據的。如果一定要傳遞數據的話,那麼只能通過Intent去綁定數據
四.Intent Flag啟動模式
前面就已經說了,系統提供了兩種方式來設置一個Activity的啟動模式,下面要講的是通過intent設置flag來設置一個Activity的啟動模式
下面來介紹一些常用的Flag
Intent.FLAG-ACTIVITY-NEW-TASK
使用一個新的Task來啟動一個Activity,但啟動的每個Aetivity都在新的Task棧中,該flag通常使用在從service中啟動的actiity場景,由於service中並不存在activity棧,所以用該flag來創建一個新的activity棧,並創建新的activity實例
FLAG-ACTIVITY-SINGLE-TOP
使用singletop模式來啟動一個Activity,與指定android:launchMode=”singleTop”效果相同
FLAG-ACTIVITY-CLEAR-Top
FLAG-ACTIVITY-NO-HISTORY使用SingleTask模式來啟動一個Activity,與指定android:launchMode=”singleTask”效果相同
使用這種模式啟動Acuvity,當該Activity啟動其他AcuVity後,該Activity就消失了,不會保留在activity棧中,例如A-B,B中以這種模式啟動C,C再啟動D,則當前activity棧為ABD五.清空任務棧
clearTaskOnLaunch系統同樣提供了清空任務棧的方法來讓我們講一個Task清空,通常情況下,我們可以在activity的標簽上使用以下幾種屬性來清空任務棧
finishTaskOnLaunchclearTaskOnLaunch屬性顧名思義,就是每次返回activity的時候,都將該activity上的所有activity清除,通過這個屬性,可以讓這個task每次初始化的時候,都只有一個activity
alwaysRetainTaskStatefinishTaskOnLaunch這個屬性和clearTaskOnLaunch有點類似,只不過clearTaskOnLaunch作用在別人身上,而finishTaskOnLaunch作用在自己身上,通過這個屬性,當離開這個activity所處的task,那麼用戶再返回的時候,該activity會被finish掉
alwaysRetainTaskState屬性給了task一道免死金牌,如果將activity這個屬性設置為true,那麼該activity所在的task將不接受任何清除命令,一直保持當前task的狀態
六.Activity任務棧使用
我們使用ActiVity任務棧的各種啟動模式和清理方法,是為了更好地使用App中actvity,合理地設置Acuvity的啟動模式會讓程序運行更有效率,用戶體驗更好。但任務棧雖好, 卻也不能濫用 如果過度地使用Activity任務棧,則會導致整個App的棧管理混亂,不利於以後程序的拓展,而且在容易出現由於任務棧導致的顯示異常,這樣的bug是很難調的.所以,在App中使用acuvity任務棧一定要根據實際項目的需要,而不是為了使用任務棧而使用任務棧。
OK,本章就到這裡,這章是理論,沒有Demo哦!
筆記下載:http://pan.baidu.com/s/1c0U7k2W 密碼:9v0g
吹在前面的話:ListView下刷新刷功能相信從事Android開發的猿友們並不陌生,包括現在Google親兒子SwipeRefreshLayout實現效果在一些APP上
ListView網上資料很多,我所知擴展性最好、最通用的代碼做個備忘。總體上來講:ListView+BaseAdapter+xml文件實現:話不多說,先貼個圖,預期效果如
本文實例講解了通知Notification使用方法,此知識點就是用作通知的顯示,包括振動、燈光、聲音等效果,分享給大家供大家參考,具體內容如下效果圖:MainActivi
引言動畫Animations在App中的作用有多重要勿需多言,彈出式的PopupWindow、Tab切換、Loding等等。Android 3.0前,Android只支持