在 Activity 的生命周期中,可以將 Activity 表現(xiàn)為 3 種狀態(tài)
- 激活態(tài):當(dāng) Acitivity 位于屏幕前端晕拆,并可以獲得用戶焦點(diǎn)甘凭、接收用戶輸入時(shí)柬批,這種狀態(tài)稱為激活態(tài),也可以稱為運(yùn)行態(tài)拐邪;
- 暫停態(tài):當(dāng) Activity 在運(yùn)行時(shí)被另一個(gè) Activity 所遮擋慰毅,但此時(shí) Activity 仍然可見(jiàn),也就是說(shuō)另一個(gè) Activity 是部分遮擋的扎阶,或者另一個(gè) Activity 是透明的或半透明的汹胃,此時(shí)Activity 處于暫停狀態(tài);
- 停止態(tài):當(dāng) Activity 被另一個(gè) Activity 完全遮擋不可見(jiàn)時(shí)處于停止?fàn)顟B(tài)东臀,這個(gè) Activity 仍然存在着饥,它保留在內(nèi)存中并保持所有狀態(tài)和成員信息,但是當(dāng)該設(shè)備內(nèi)存不足時(shí)惰赋,該 Activity 可能會(huì)被系統(tǒng)殺掉以釋放其占用的內(nèi)存空間贱勃,當(dāng)再次打開(kāi)該 Activity 時(shí),它會(huì)被重新創(chuàng)建;
Activity 生命周期中的 7 個(gè)方法
- onCreate():當(dāng) Activity 被創(chuàng)建時(shí)調(diào)用贵扰;
- onStart():當(dāng) Activity 被創(chuàng)建后即將可見(jiàn)時(shí)調(diào)用仇穗;
- onResume():(繼續(xù)開(kāi)始)當(dāng) Activity 位于設(shè)備最前端,對(duì)用戶可見(jiàn)時(shí)調(diào)用戚绕;
- onPause():(暫停)當(dāng)另一個(gè) Activity 遮擋當(dāng)前 Activity纹坐,當(dāng)前 Activity 被切換到后臺(tái)時(shí)調(diào)用;
- onRestart():(重新啟動(dòng))當(dāng)另一個(gè) Activity 執(zhí)行完 onStop()方法舞丛,又被用戶打開(kāi)時(shí)調(diào)用耘子;
- onStop():如果另一個(gè) Activity 完全遮擋了當(dāng)前 Activity 時(shí),該方法被調(diào)用球切;
- onDestory():當(dāng) Activity 被銷毀時(shí)調(diào)用谷誓;
Activity 的四種啟動(dòng)模式及使用場(chǎng)景
Standard、SingleTop吨凑、SingleTask 和 SingleInstance捍歪,他們是在配置文件中通過(guò) android:launchMode 屬性配置;
- Standard:默認(rèn)的啟動(dòng)模式鸵钝,每次啟動(dòng)會(huì)在任務(wù)棧中新建一個(gè)啟動(dòng)的 Activity 的實(shí)例糙臼;
- SingleTop:如果要啟動(dòng)的 Activity 實(shí)例已位于棧頂,則不會(huì)重新創(chuàng)建該 Activity 的實(shí)例恩商,否則會(huì)產(chǎn)生一個(gè)新的運(yùn)行實(shí)例变逃;
- SingleTask:如果棧中有該 Activity 實(shí)例,則直接啟動(dòng)怠堪,中間的 Activity 實(shí)例將會(huì)被關(guān)閉揽乱,關(guān)閉的順序與啟動(dòng)的順序相同;
- SingleInstance:該啟動(dòng)模式會(huì)在啟動(dòng)一個(gè) Activity 時(shí)粟矿,啟動(dòng)一個(gè)新的任務(wù)棧凰棉,將該 Activity實(shí)例放置在這個(gè)任務(wù)棧中,并且該任務(wù)棧中不會(huì)再保存其他的 Activity 實(shí)例嚷炉;
Activity 任務(wù)棧
即存放 Activity 任務(wù)的棧渊啰,每打開(kāi)一個(gè) Activity 時(shí)就會(huì)往 Activity 棧中壓入一個(gè) Activity 任務(wù),每當(dāng)銷毀一個(gè) Activity 的時(shí)候申屹,就會(huì)從 Activity 任務(wù)棧中彈出一個(gè) Activity 任務(wù)绘证,由于安卓手機(jī)的限制,只能從手機(jī)屏幕獲取當(dāng)前一個(gè) Activity 的焦點(diǎn)哗讥,即棧頂元素(最上面的 Activity)嚷那,其余的 Activity 會(huì)暫居后臺(tái)等待系統(tǒng)的調(diào)用;
關(guān)于任務(wù)棧的更多概念:當(dāng)App打開(kāi)時(shí)就創(chuàng)建了一個(gè)任務(wù)棧杆煞,用于存儲(chǔ)當(dāng)前App的 Activity魏宽,當(dāng)前App(包括被當(dāng)前App所調(diào)用的)所有的 Activity 都屬于一個(gè)任務(wù)棧腐泻;一個(gè)任務(wù)棧包含了一個(gè) Activity 的集合,可以有序的選擇哪個(gè) Activity 和用戶進(jìn)行交互队询,只有任務(wù)棧頂?shù)腁ctivity 才可以與用戶進(jìn)行交互派桩;任務(wù)棧可以移動(dòng)到后臺(tái)蚌斩,并保留每一個(gè) Activity 的狀態(tài)铆惑,并且有序的給用戶列出他們的任務(wù),而且還不會(huì)丟失他們的狀態(tài)信息送膳;退出應(yīng)用程序時(shí)员魏,當(dāng)把所有的任務(wù)棧中所有的 Activity 清除出棧時(shí),任務(wù)棧會(huì)被銷毀叠聋,程序退出撕阎;
Fragment
Android3.0 引入 Fragment 技術(shù),譯為“碎片”碌补,在 Activity 中可以通過(guò) FragmentManager來(lái)添加虏束、移除和管理所加入的 Fragment,每個(gè) Fragment 都有自己的布局脑慧、生命周期魄眉、交互事件的處理砰盐,由于Fragment 是嵌入到 Activity 中的闷袒,所以 Fragment 的生命周期又和 Activity的生命周期有密切的關(guān)聯(lián)。
Fragment 的生命周期的方法
1.onAttach():當(dāng) Fagment 和 Activity 產(chǎn)生關(guān)聯(lián)時(shí)被調(diào)用岩梳;
2.onCreate():當(dāng) Fragment 被創(chuàng)建時(shí)調(diào)用囊骤;
3.onCreateView():創(chuàng)建并返回與 Fragment 相關(guān)的 view 界面;
4.onViewCreate():在 onCreateView()執(zhí)行完后立即執(zhí)行冀值;
5.onActivityCreated():通知 Fragment也物,他所關(guān)聯(lián)的 Activity 已經(jīng)完成了 onCreate()的調(diào)用;
6.onStart():讓 Fragment 準(zhǔn)備可以被用戶所見(jiàn)列疗,該方法和 Activity 的 onStart()方法相關(guān)聯(lián)滑蚯;
7.onResume():Fragment 可見(jiàn),可以和用戶交互抵栈,該方法和 Activity 的 onResume()方法相關(guān)聯(lián)告材;
8.onPause():當(dāng)用戶離開(kāi) Fragment 時(shí)調(diào)用該方法,此操作是由于所在的 Activity 被遮擋或者是在 Activity 中的另一個(gè) Fragment 操作所引起的古劲;
9.onStop():對(duì)用戶而言斥赋,F(xiàn)ragment 不可見(jiàn)時(shí)調(diào)用該方法,此操作是由于他所在的 Activity不再可見(jiàn)或者是在 Activity 中的一個(gè) Fragment 操作所引起的产艾;
10.onDestroyView():ment 清理和它的 view 相關(guān)的資源疤剑;
11.onDestroy(): 最終清理 Fragment 的狀態(tài)滑绒;
12.onDetach():Fragment 與 Activity 不再產(chǎn)生關(guān)聯(lián);
Fragment 加載布局 文件是在 onCreateView()方法中使 用 LayoutInflater( 布局加載 器)的
inflate( )方法加載布局文件隘膘。
管理 Fragment
通過(guò)調(diào)用 Context 的 getFragmentManager()方法或者 getSupportFragmentManager()方法(這
兩個(gè)方法需要導(dǎo)入的包不同)來(lái)獲取 FragmentManager疑故,使用 FragmentManager 對(duì)象,主要
可以調(diào)用如下方法:
findFragmentById()/findFragmentByTag():獲取 Activity 中已經(jīng)存在的 Fragment弯菊;
getFragments():獲取所有加入 Activity 中的 Fragment焰扳;
begainTransaction():獲取一個(gè) FragmentTransaction 對(duì)象,用來(lái)執(zhí)行 Fragment 的事物误续;
popBackStack():從 Activity 的后退棧中彈出 Fragment吨悍;
addOnBackChagedListerner:注冊(cè)一個(gè)偵聽(tīng)器以監(jiān)視后退棧的變化;
FragmentTransaction
在 Activity 中對(duì) Fragment 進(jìn)行添加蹋嵌、刪除育瓜、替換以及執(zhí)行其他的動(dòng)作將引起 Fragment 的變化,叫做一個(gè)事務(wù)栽烂,事務(wù)是通過(guò) FragmentTransaction 來(lái)執(zhí)行的躏仇,可以用 add()、remove()腺办、replace()焰手、show()、hide()等方法構(gòu)成事務(wù)怀喉,最后使 commit()提交事務(wù)书妻,參考代碼 :
getSupportFragmentManager().beginTransaction().add(R.id.main_container, t Fragment).add(R.i
d.main_container, e Fragment).hide(e Fragment).commit();其中 R.id.main_container 為布局中容納 Fragment 的 view 的 ID躬拢。
保存 Activity 狀態(tài)
onSaveInstanceState(Bundle)會(huì)在 Activity 轉(zhuǎn)入后臺(tái)狀態(tài)之前被調(diào)用躲履,也就是 onStop()方法之前,onPause()方法之后被調(diào)用
Fragment 與 Fragment聊闯、Activity 通信的方式
1.EventBus
2.使用接口
3.Fragment 直接調(diào)用 Activity 中的 public 方法
Android四大組件
- Activity:用戶可操作的可視化界面工猜,為用戶提供一個(gè)完成操作指令的窗口。一個(gè) Activity 通常是一個(gè)單獨(dú)的屏幕菱蔬,Activity 通過(guò) Intent 來(lái)進(jìn)行通信篷帅。Android 中會(huì)維持一個(gè) Activity Stack,當(dāng)一個(gè)新 Activity 創(chuàng)建時(shí)拴泌,它就會(huì)放到棧頂魏身,這個(gè) Activity 就處于運(yùn)行狀態(tài)。
- Service:服務(wù)弛针,運(yùn)行在手機(jī)后臺(tái)叠骑,適合執(zhí)行不需和用戶交互且還需長(zhǎng)期運(yùn)行的任務(wù)。
- ContentProvider:內(nèi)容提供者削茁,使一個(gè)應(yīng)用程序的指定數(shù)據(jù)集提供給其他應(yīng)用程序宙枷,其他應(yīng)用可通過(guò) ContentResolver 類從該內(nèi)容提供者中獲取或存入數(shù)據(jù)掉房。它提供了一種跨進(jìn)程數(shù)據(jù)共享的方式,當(dāng)數(shù)據(jù)被修改后慰丛,ContentResolver 接口的 notifyChange 函數(shù)通知那些注冊(cè)監(jiān)控特定 URI 的 ContentObserver 對(duì)象卓囚。如果 ContentProvider 和調(diào)用者在同一進(jìn)程中,ContentProvider 的方法(query/insert/update/delete 等)和調(diào)用者在同一線程中诅病;如果 ContentProvider和調(diào)用者不在同一進(jìn)程哪亿,ContentProvider 方法會(huì)運(yùn)行在它自身進(jìn)程的一個(gè) Binder 線程中。
- BroadcastReceiver:廣播接收者贤笆,運(yùn)用在應(yīng)用程序間傳輸信息蝇棉,可以使用廣播接收器來(lái)讓?xiě)?yīng)用對(duì)一個(gè)外部事件做出響應(yīng)。
Activity 之間的通信方式
1.通過(guò) Intent 方式傳遞參數(shù)跳轉(zhuǎn)
2.借助類的靜態(tài)變量或全局變量
3.借助 SharedPreference 或是外部存儲(chǔ)芥永,如數(shù)據(jù)庫(kù)或本地文件
4.EventBus(普通事件或粘性事件)
橫豎屏切換的時(shí)候篡殷,Activity 各種情況下的生命周期
- 切換橫屏?xí)r:onSaveInstanceState -> onPause -> onStop -> onDestory -> onCreate -> o
nStart -> onRestoreInstanceState -> onResume - 切換豎屏?xí)r:會(huì)打印兩次相同的 log,onSaveInstanceState -> onPause -> onStop -> onD
estory -> onCreate -> onStart -> onRestoreInstanceState -> onResume -> onSaveInstanceSt
ate -> onPause -> onStop -> onDestory -> onCreate -> onStart -> onRestoreInstanceState
-> onResume - 如果在 AndroidMainfest.xml 中修改該 Activity 的屬性埋涧,添加 android:configChanges="orient
ation"橫豎屏切換板辽,打印的 log 一樣同 1) - 如果 AndroidMainfest.xml 中該 Activity 中的 android:configChanges="orientation|keyboardH
idden",則只會(huì)打印 onConfigurationChanged
Activity 狀態(tài)保存于恢復(fù)
Activity 被主動(dòng)回收時(shí)棘催,如按下 Back 鍵劲弦,系統(tǒng)不會(huì)保存它的狀態(tài),只有被動(dòng)回收時(shí)醇坝。雖然這個(gè) Activity 實(shí)例已被銷毀邑跪,但系統(tǒng)在新建一個(gè) Activity 實(shí)例時(shí),會(huì)帶上先前被回收 Activity的信息纲仍。在當(dāng)前 Activiy 被銷毀前調(diào)用 onSaveInstanceState(onPause 和 onStop 之間保存)呀袱,重新創(chuàng)建 Activity 后會(huì)在 onCreate 后調(diào)用 onRestoreInstanceState(onStar 和 onResume)之間被調(diào)用)贸毕,它們的參數(shù) Bundle 用來(lái)數(shù)據(jù)保存和讀取的郑叠。保存 View 狀態(tài)有兩個(gè)前提:View 的子類必須實(shí)現(xiàn)了 onSaveInstanceState; 必須要設(shè)定 Id,這個(gè) ID 作為 Bundle 的 Key
IntentService 原理及作用是什么
IntentService 是繼承 Service 的一個(gè)抽象類明棍,它在 onCreate()方法中創(chuàng)建了一個(gè) HandlerThread乡革,并啟動(dòng)該線程。HandlerThread 是帶有自己消息隊(duì)列和 Looper 的線程摊腋,根據(jù) HandlerThread的 looper 創(chuàng)建一個(gè) Handler沸版,這樣 IntentService 的 ServiceHandler 的 handleMessage()方法就運(yùn)行在子線程中。handleMessage 中調(diào)用了 onHandleIntent()方法兴蒸,它是一個(gè)抽象方法视粮,繼承IntentService 類需要實(shí)現(xiàn)該方法,把耗時(shí)操作放在 onHandleIntent()方法中橙凳,等耗時(shí)操作運(yùn)行完成后蕾殴,會(huì)調(diào)用 stopSelf()方法笑撞,服務(wù)會(huì)調(diào)用 onDestory()方法消毀自己。如果 onHandleIntent()中的耗時(shí)操作未運(yùn)行完前就調(diào)用了 stopSelf()方法钓觉,服務(wù)調(diào)用 onDestory()方法茴肥,但耗時(shí)操作會(huì)繼續(xù)運(yùn)行,直至運(yùn)行完畢荡灾。如果同時(shí)多次啟動(dòng) IntentService瓤狐,任務(wù)會(huì)放在一個(gè)隊(duì)列中,onCreate()和 onDestory()方法都只會(huì)運(yùn)行一次批幌。作用:用來(lái)處理后臺(tái)耗時(shí)操作础锐,如讀取數(shù)據(jù)
庫(kù)或是本地文件等。
說(shuō)說(shuō) ContentProvider荧缘、ContentResolver郁稍、ContentObserver 之間的關(guān)系
- ContentProvider 實(shí)現(xiàn)各個(gè)應(yīng)用程序間數(shù)據(jù)共享,用來(lái)提供內(nèi)容給別的應(yīng)用操作胜宇。如聯(lián)系人應(yīng)用中就使用了 ContentProvider耀怜,可以在自己應(yīng)用中讀取和修改聯(lián)系人信息,不過(guò)需要獲取相應(yīng)的權(quán)限桐愉。它也只是一個(gè)中間件财破,真正的數(shù)據(jù)源是文件或 SQLite 等。
- ContentResolver 內(nèi)容解析者从诲,用于獲取內(nèi)容提供者提供的數(shù)據(jù)左痢,通過(guò) ContentResolver.notifyChange(uri)發(fā)出消息。
- ContentObserver 內(nèi)容監(jiān)聽(tīng)者系洛,可以監(jiān)聽(tīng)數(shù)據(jù)的改變狀態(tài)俊性,觀察特定 Uri 引起的數(shù)據(jù)庫(kù)變化,繼而做一些相應(yīng)的處理描扯,類似于數(shù)據(jù)庫(kù)中的觸發(fā)器定页,當(dāng) ContentObserver 所觀察的 Uri 發(fā)生變化時(shí),便會(huì)觸發(fā)它绽诚。
BroadcastReceiver(廣播)的分類
- 普通廣播:完全異步的典徊,可以在同一時(shí)刻(邏輯上)被所有接收者接收到,消息傳遞的效率比較高恩够,并且無(wú)法中斷廣播的傳播卒落。
- 有序廣播:發(fā)送有序廣播后,廣播接收者將按預(yù)先聲明的優(yōu)先級(jí)依次接收 Broadcast蜂桶。優(yōu)先級(jí)高的優(yōu)先接收到廣播儡毕,而在其 onReceiver()執(zhí)行過(guò)程中,廣播不會(huì)傳播到下一個(gè)接收者扑媚,此時(shí)當(dāng)前的廣播接收者可以 abortBroadcast()來(lái)終止廣播繼續(xù)向下傳播腰湾,也可以將 intent中的數(shù)據(jù)進(jìn)行修改設(shè)置贾费,然后將其傳播到下一個(gè)廣播接收者。sendOrderedBroadcast(intent, null);//發(fā)送有序廣播
- 粘性廣播:sendStickyBroadcast()來(lái)發(fā)送該類型的廣播信息檐盟,這種廣播的最大特點(diǎn)是褂萧,當(dāng)粘性廣播發(fā)送后,最后的一個(gè)粘性廣播會(huì)滯留在操作系統(tǒng)中葵萎。如果在粘性廣播發(fā)送后的一段時(shí)間里导犹,如果有新的符合廣播的動(dòng)態(tài)注冊(cè)的廣播接收者注冊(cè),將會(huì)收到這個(gè)廣播消息羡忘,雖然這個(gè)廣播是在廣播接收者注冊(cè)之前發(fā)送的谎痢,另外一點(diǎn),對(duì)于靜態(tài)注冊(cè)的廣播接收者來(lái)說(shuō)卷雕,這個(gè)等同于普通廣播节猿。
本地廣播和全局廣播有什么差別
- LocalBroadcastReceiver 僅在自己的應(yīng)用內(nèi)發(fā)送接收廣播,也就是只有自己的應(yīng)用能收到漫雕,數(shù)據(jù)更加安全滨嘱。廣播只在這個(gè)程序里,而且效率更高浸间。只能動(dòng)態(tài)注冊(cè)太雨,在發(fā)送和注冊(cè)的時(shí)候采用 LocalBroadcastManager 的 sendBroadcast 方法和 registerReceiver 方法。
- 全局廣播:發(fā)送的廣播事件可被其他應(yīng)用程序獲取魁蒜,也能響應(yīng)其他應(yīng)用程序發(fā)送的廣播事件(可以通過(guò) exported–是否監(jiān)聽(tīng)其他應(yīng)用程序發(fā)送的廣播在清單文件中控制)全局廣播既可以動(dòng)態(tài)注冊(cè)囊扳,也可以靜態(tài)注冊(cè)。
Dialog兜看、PopupWindow 區(qū)別
- PopupWindow 在顯示之前一定要設(shè)置寬高锥咸,Dialog 無(wú)此限制;
- PopupWindow 默認(rèn)不會(huì)響應(yīng)物理鍵盤(pán)的 back细移,除非顯示設(shè)置了 popup.setFocusable(true);而在點(diǎn)擊 back 的時(shí)候搏予,Dialog 會(huì)消失;
- PopupWindow 不會(huì)給頁(yè)面其他的部分添加蒙層葫哗,而 Dialog 會(huì)缔刹;
- PopupWindow 沒(méi)有標(biāo)題,Dialog 默認(rèn)有標(biāo)題劣针,可以通過(guò) dialog.requestWindowFeature(Wi
ndow.FEATURE_NO_TITLE);取消標(biāo)題; - 二者顯示的時(shí)候都要設(shè)置 Gravity亿扁。如果不設(shè)置捺典,Dialog 默認(rèn)是 Gravity.CENTER;
- 二者都有默認(rèn)的背景从祝,都可以通過(guò) setBackgroundDrawable(new ColorDrawable(android.R.
color.transparent));去掉襟己; - PopupWindow 彈出后引谜,取得了用戶操作的響應(yīng)處理權(quán)限,使得其他 UI 控件不被觸發(fā)擎浴。而AlertDialog 彈出后员咽,點(diǎn)擊背景,AlertDialog 會(huì)消失贮预;
Application 和 Activity 的 Context 對(duì)象的區(qū)別
一個(gè)應(yīng)用 Context 的數(shù)量 = Activity 數(shù)量 + Service 數(shù)量 + 1(Application 數(shù)量)