Activity
Activity生命周期:
啟動Activity: onCreate()—>onStart()—>onResume(),Activity進入運行狀態(tài)。
Activity退居后臺: 當前Activity轉到新的Activity界面或按Home鍵回到主屏: onPause()—>onStop(),進入停滯狀態(tài)。
Activity返回前臺: onRestart()—>onStart()—>onResume(),再次回到運行狀態(tài)。
Activity退居后臺,且系統(tǒng)內存不足, 系統(tǒng)會殺死這個后臺狀態(tài)的Activity(此時這個Activity引用仍然處在任務棧中,只是這個時候引用指向的對象已經(jīng)為null),若再次回到這個Activity,則會走onCreate()–>onStart()—>onResume()(將重新走一次Activity的初始化生命周期)
鎖屏:onPause()->onStop()
解鎖:onStart()->onResume()

Activity的簡單生命周期流程為onCreate();→onStart();【注:此時Activity處于不可見狀態(tài)】→onResume();【注:此時Activity處于運行狀態(tài)】→onPause();【注:此時Activity處于暫停狀態(tài)】→onStop();【注:此時Activity處于停滯狀態(tài)】→onDestroy();【注:調用了此方法后Activity生命周期結束】
Activity的四種啟動模式
使用android:launchMode="standard|singleInstance|singleTask|singleTop"來控制Acivity任務棧。
任務棧是一種后進先出的結構。位于棧頂?shù)腁ctivity處于焦點狀態(tài),當按下back按鈕的時候,棧內的Activity會一個一個的出棧,并且調用其onDestory()方法。如果棧內沒有Activity,那么系統(tǒng)就會回收這個棧,每個APP默認只有一個棧,以APP的包名來命名.
standard : 標準模式,每次啟動Activity都會創(chuàng)建一個新的Activity實例,并且將其壓入任務棧棧頂,而不管這個Activity是否已經(jīng)存在。Activity的啟動三回調(onCreate()->onStart()->onResume())都會執(zhí)行。
singleTop : 棧頂復用模式.這種模式下,如果新Activity已經(jīng)位于任務棧的棧頂,那么此Activity不會被重新創(chuàng)建,所以它的啟動三回調就不會執(zhí)行,同時Activity的onNewIntent()方法會被回調.如果Activity已經(jīng)存在但是不在棧頂,那么作用與standard模式一樣.
singleTask: 棧內復用模式.創(chuàng)建這樣的Activity的時候,系統(tǒng)會先確認它所需任務棧已經(jīng)創(chuàng)建,否則先創(chuàng)建任務棧.然后放入Activity,如果棧中已經(jīng)有一個Activity實例,那么這個Activity就會被調到棧頂,onNewIntent(),并且singleTask會清理在當前Activity上面的所有Activity.(clear top)
singleInstance : 加強版的singleTask模式,這種模式的Activity只能單獨位于一個任務棧內,由于棧內復用的特性,后續(xù)請求均不會創(chuàng)建新的Activity,除非這個獨特的任務棧被系統(tǒng)銷毀了
Activity緩存方法
有a、b兩個Activity,當從a進入b之后一段時間,可能系統(tǒng)會把a回收,這時候按back,執(zhí)行的不是a的onRestart而是onCreate方法,a被重新創(chuàng)建一次,這是a中的臨時數(shù)據(jù)和狀態(tài)可能就丟失了。
可以用Activity中的onSaveInstanceState()回調方法保存臨時數(shù)據(jù)和狀態(tài),這個方法一定會在活動被回收之前調用。方法中有一個Bundle參數(shù),putString()、putInt()等方法需要傳入兩個參數(shù),一個鍵一個值。數(shù)據(jù)保存之后會在onCreate中恢復,onCreate也有一個Bundle類型的參數(shù)。
示例代碼:

一、onSaveInstanceState (Bundle outState)
當某個activity變得“容易”被系統(tǒng)銷毀時,該activity的onSaveInstanceState就會被執(zhí)行,除非該activity是被用戶主動銷毀的,例如當用戶按BACK鍵的時候。
注意上面的雙引號,何為“容易”?言下之意就是該activity還沒有被銷毀,而僅僅是一種可能性。這種可能性有哪些?通過重寫一個activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我們可以清楚地知道當某個activity(假定為activity A)顯示在當前task的最上層時,其onSaveInstanceState方法會在什么時候被執(zhí)行,有這么幾種情況:
1、當用戶按下HOME鍵時。
這是顯而易見的,系統(tǒng)不知道你按下HOME后要運行多少其他的程序,自然也不知道activity A是否會被銷毀,故系統(tǒng)會調用onSaveInstanceState,讓用戶有機會保存某些非永久性的數(shù)據(jù)。以下幾種情況的分析都遵循該原則
2、長按HOME鍵,選擇運行其他的程序時。
3、按下電源按鍵(關閉屏幕顯示)時。
4、從activity A中啟動一個新的activity時。
5、屏幕方向切換時,例如從豎屏切換到橫屏時。(如果不指定configchange屬性) 在屏幕切換之前,系統(tǒng)會銷毀activity A,在屏幕切換之后系統(tǒng)又會自動地創(chuàng)建activity A,所以onSaveInstanceState一定會被執(zhí)行
總而言之,onSaveInstanceState的調用遵循一個重要原則,即當系統(tǒng)“未經(jīng)你許可”時銷毀了你的activity,則onSaveInstanceState會被系統(tǒng)調用,這是系統(tǒng)的責任,因為它必須要提供一個機會讓你保存你的數(shù)據(jù)(當然你不保存那就隨便你了)。另外,需要注意的幾點:
1.布局中的每一個View默認實現(xiàn)了onSaveInstanceState()方法,這樣的話,這個UI的任何改變都會自動地存儲和在activity重新創(chuàng)建的時候自動地恢復。但是這種情況只有在你為這個UI提供了唯一的ID之后才起作用,如果沒有提供ID,app將不會存儲它的狀態(tài)。
2.由于默認的onSaveInstanceState()方法的實現(xiàn)幫助UI存儲它的狀態(tài),所以如果你需要覆蓋這個方法去存儲額外的狀態(tài)信息,你應該在執(zhí)行任何代碼之前都調用父類的onSaveInstanceState()方法(super.onSaveInstanceState())。 既然有現(xiàn)成的可用,那么我們到底還要不要自己實現(xiàn)onSaveInstanceState()?這得看情況了,如果你自己的派生類中有變量影響到UI,或你程序的行為,當然就要把這個變量也保存了,那么就需要自己實現(xiàn),否則就不需要。
3.由于onSaveInstanceState()方法調用的不確定性,你應該只使用這個方法去記錄activity的瞬間狀態(tài)(UI的狀態(tài))。不應該用這個方法去存儲持久化數(shù)據(jù)。當用戶離開這個activity的時候應該在onPause()方法中存儲持久化數(shù)據(jù)(例如應該被存儲到數(shù)據(jù)庫中的數(shù)據(jù))。
4.onSaveInstanceState()如果被調用,這個方法會在onStop()前被觸發(fā),但系統(tǒng)并不保證是否在onPause()之前或者之后觸發(fā)。
二、onRestoreInstanceState (Bundle outState)
至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成對的被調用的,(本人注:我昨晚調試時就發(fā)現(xiàn)原來不一定成對被調用的?。?/p>
onRestoreInstanceState被調用的前提是,activity A“確實”被系統(tǒng)銷毀了,而如果僅僅是停留在有這種可能性的情況下,則該方法不會被調用,例如,當正在顯示activity A的時候,用戶按下HOME鍵回到主界面,然后用戶緊接著又返回到activity A,這種情況下activity A一般不會因為內存的原因被系統(tǒng)銷毀,故activity A的onRestoreInstanceState方法不會被執(zhí)行
另外,onRestoreInstanceState的bundle參數(shù)也會傳遞到onCreate方法中,你也可以選擇在onCreate方法中做數(shù)據(jù)還原。 還有onRestoreInstanceState在onstart之后執(zhí)行。 至于這兩個函數(shù)的使用,給出示范代碼(留意自定義代碼在調用super的前或后):

Service
Service分為兩種,一種是Service(這一種是運行在主線程中的,如果要執(zhí)行耗時操作,可在service中創(chuàng)建一個異步來執(zhí)行),一種是IntentService(這是一種異步服務,是繼承于Service的子類),所以推薦當要執(zhí)行耗時操作時使用IntentService,如果不耗時,我們可以使用Service
創(chuàng)建一個類繼承Service

? ? ?在manifest里注冊

Service兩種啟動方式:
通過startService方法啟動服務

當不用服務的時候通過stopService()方法停止該服務
????????????????????????????????????????????????stopService(intent);
特點: 通過start方法啟動的service一旦服務開啟就跟調用者(開啟者)沒有任何關系了。開啟者退出了,開啟者掛了,服務還在后臺長期的運行,開啟者不能調用服務里面的方法
通過bind的方式啟動服務
Intent intent=newIntent(this,MyService.class);
bindService(Intent,ServiceConnection,int);
當不用服務的時候通過stopService()方法停止該服務
unbindService(ServiceConnection);
特點:使用bind方法啟動的服務,則調用者掛了,服務也掛了,調用者可以調用服務中的方法