天天看點

[android]android5大基礎元件深入分析

activity —— 應用表示層(基類activity) 

       應用程式中的每個螢幕都是通過繼承和擴充基類activity來實作的。 

       同一應用中的每個activity是互相獨立的。程式啟動後顯示的第一幅畫面是應用程式的第一個activity(預設視窗),而後可以根據需要從這個activity啟動另一個新的activity。 

       activity利用view來實作應用中的gui(使用者直接通過gui和應用程式做互動)。activity視窗内的可見内容通過基類view提供。使用activity.setcontentview()方法設定目前activity中的view對象。 

l         每個view對象控制着視窗内的一個矩形空間; 

l         view是一種階層化結構,parent view中的布局屬性會被子view繼承; 

l         位于view層次關系最底層的子view對象所代表的矩形空間就是跟使用者進行互動的地方

service —— 沒有可見的使用者界面,但能夠長時間運作于背景(基類service) 

       運作于應用程式程序的主線程中,是以service不會阻塞其他元件和使用者界面。 

       service是不能自己啟動的,必須通過context對象(如一個activity)調用startservice或bindservice方法來啟動(用這兩種方法啟動的service的生命周期不同)。 

1.         調用startservice方法 

a)         若service沒有啟動,則首先會調用該service的oncreate方法,然後再調用onstart方法。 

b)        若service已經啟動,則會直接調用onstart方法 

c)        該方法啟動的service,可以通過context對象調用stopservice來關閉,也可以通過service自身調用stopself()或stopselfresult()來關閉,關閉之前調用ondestory方法。 

2.         調用bindservice方法,使目前context對象通過一個serviceconnection的對象綁定到所指定的service 

a)         若service沒有啟動,則首先會調用該service的oncreate方法初始化啟動,然後調用service的onbind方法初始化綁定。 

b)        如果綁定service的context對象被銷毀時,被綁定的service也會調用onunbind 和 ondestroy方法停止運作

c)        注意: broadcastreceiver是不能綁定服務的。 

d)        一個綁定service的context對象還可以通過unbindservice()來取消對服務的綁定。 

e)         取消時,service會調用unbind方法,若service是通過bindservice來啟動的,還會調用ondestroy方法來停止服務。 

broadcast receiver —— 使用者接收廣播通知的元件(基類broadcastreceiver) 

       android中的廣播要麼來自于系統,要麼來自普通應用程式。 

很多事件都可能導緻系統廣播,如手機所在時區發生變化,電池電量低,使用者改變系統語言設定等。 

來自普通應用程式,如一個應用程式通知其他應用程式某些資料已經下載下傳完畢。 

       為了響應不同的事件通知,應用程式可以注冊不同的broadcast receiver。所有的broadcast receiver都繼承自基類broadcastreceiver。 

       broadcastreceiver自身并不實作圖形使用者界面,但是當它收到某個通知後,broadcastreceiver可以啟動activity作為響應,或者通過notificationmananger提醒使用者。 

       broadcastreceiver是對發送出來的broadcast進行過濾接收并響應的一類元件。 

       發送broadcast資訊 

1.         把要發送的資訊和用于過濾得資訊(如action、category)裝入一個intent對象 

2.         調用context.sendbroadcast()、sendorderbroadcast()、sendstickybroadcast()方法,廣播該intent對象 

3.         使用sendbroadcast() 或sendstickybroadcast()方法發出去的intent,所有滿足條件的broadcastreceiver都會随機地執行其onreceive()方法; 

4.         而sendorderbroadcast()發出去的intent,會根據broadcastreceiver注冊時intentfilter設定的優先級的順序來執行,相同優先級的broadcastreceiver則是随機執行 

5.         sendstickybroadcast()方法主要的不同是,intent在發送後一直存在,并且在以後調用registerreceiver()注冊相比對的intent時會把這個intent直接傳回。 

6.         若在使用sendbroadcast()方法時指定了接收的權限,這隻有在androidmanifest.xml中用<uses-permission>标簽聲明了擁有此權限的broadcastreceiver才會有可能接收到發送來broadcast。 

7.         若在注冊broadcastreciever時,指定了可接收的broadcast的權限,則隻有在包内的androidmanifest.xml中用<uses-permission>标簽聲明了,擁有此權限的context對象所發送的broadcast才有可能被這個broadcastreceiver所接收。 

接收broadcast消息 

1.         繼承broadcastreceiver 類,并實作onreceive方法 

2.         注冊broadcast receiver(有2種方法:一種方法是,靜态地在androidmanifest.xml中用<receiver>标簽聲明,并在标簽内用<intent-filter>标簽設定過濾器; 另一種方法,動态地在代碼中先定義并設定好一個intentfilter對象,然後再需要注冊的地方調用context.registerreceiver()方法) (取消注冊時,調用context.unregisterreceiver()方法) 

content provider —— 為解決應用程式間資料通信、共享的問題(基類contentprovider) 

       在android中,每個應用程式都是用自己的使用者id并在自己的程序中運作。這樣的好處是,可以有效地保護系統及應用程式,避免被其他不正常德應用程式所影響,每個程序都擁有獨立的程序位址空間和虛拟空間。 

       content provider可以将應用程式特定的資料提供給另一個應用程式使用。其資料存儲方式可以是android檔案系統、sqlite資料庫或者其他合理的方式。 

       當資料需要在應用程式間共享時,我們就可以利用contentprovider為資料定義一個uri。之後,其他應用程式對資料進行查詢或者修改時,隻需要從目前上下文對象獲得一個contentresolver, 然後傳入響應的uri就可以了。 

       content provider 繼承自基類contentprovider,并且實作了一組标準接口。通過這組接口,其他應用程式能對資料進行讀寫和存儲。然而,需要使用資料的應用程式并不是直接調用這組方法,而是通過調用contentresolver對象的方法來完成。contentresolver對象可以與任意contentprovider通信。 

       要為目前應用程式的私有資料定義uri,就需要專門定義一個繼承自contentprovider的類,然後根據不同的操作調用的方法去實作這些方法的功能。 

       contentresolver類為應用程式提供了接入content機制的方法。要構造一個contentresolver對象可以為構造方法contentresolver(context context)傳入一個context對象,也可以直接通過context對象調用getcontentresolver()方法獲得 —— 有的contentresolver對象後,就可以通過調用其query()、insert()、update()等方法來對資料進行操作了。 

一旦需要以上4種android應用程式基本元件完成請求,android會首先确認該元件所在程序是否運作,如果沒有運作,android将先啟動程序,同時确認被請求元件的執行個體是否存在,否則将建立一個新的元件執行個體。 

intent —— 連接配接元件的紐帶 

       以上4種基本元件中,除了content provider是通過content resolver激活外,其他3種元件activity、service和broadcast receiver都是由intent異步消息激活的。 

       intent在不同的元件之間傳遞消息,将一個元件的請求意圖傳給另一個元件。是以,intent是包含具體請求資訊的對象。 

針對不同的元件,intent所包含的消息内容有所不同,且不同元件的激活方式也不同, 且不同類型元件有傳遞intent的不同方式。 

       intent是一種運作時綁定(runtime binding)機制,它能夠在程式運作的過程中連接配接兩個不同的元件。通過intent,你的程式可以向android表到某種請求或者意願,android會根據意願的内容選擇适當的元件來處理請求。 

l         激活一個新的activity,或者讓一個現有的activity執行一個新的操作,可以通過調用如下兩種方法(這兩彙總方法需要傳入的intent參數稱為activity action intent): 

1.         context.startactivity() 

2.         activity.startactivityforresult() 

l         啟動一個新的服務,或者向一個已有的服務傳遞新的指令,可以調用如下兩種方法: 

1.         context.startservice() 

2.         context.bindservice() 

l         發送廣播intent(所有已注冊的擁有與之相比對intenfilter的broadcastreceiv就會被激活),可以調用如下三種方法: 

1.         context.sendbroadcast() 

2.         context.sendorderbroadcast() 

3.         context.sendstickbroadcast() 

intent一旦發出,android都會準确找到相比對的一個或多個activity、service或broadcastreceiver作響應。是以,不同類型的intent消息不會出現重疊,broadcastintent消息隻會發送給broadcastreceiver,而絕不可能發送給activity或server。有startactivity()傳遞的消息也隻可能發送給activity,由startservice()傳遞的intent隻可能發送給service。 

       intent對象抽象地描述了執行操作,intent的主要組成部分; 

1.         目标元件名稱。[可選項] 

a)         元件名稱是一個componentname對象,是目标元件類名和目标元件所在應用程式包的組合 

b)        元件中的包名不一定要和manifes檔案中包名完全比對 

c)        如果intent消息中指明了目标元件的名稱,這就是一個顯示消息,intent會傳遞給指明的元件。 

d)        如果目标元件名稱并沒有指定,android則通過intent内的其他資訊和已注冊的intentfilter的比較來選擇合适的目标元件 

2.         action [隐式比較] 

a)         描述intent所觸發動作的名字字元串。 

b)        理論上action可以為任何字元串,而與android系統應用有關的action字元串以靜态字元串常量的形式定義在了intent類中。 

3.         data [隐式比較] 

a)         描述intent要操作的的資料的uri和資料類型。 

b)        正确設定intent的資料對于android尋找系統中比對intent請求的元件很重要。 

4.         category [隐式比較] 

a)         是對被請求元件的額外描述資訊。 

b)        android也在intent類中定義了一組靜态字元串常量表示intent不同的類别。 

5.         extra 

a)         當我們使用intent連接配接不同元件時,有時需要在intent中附加額外的資訊,以便将資料傳遞給目标activity。

b)        extra用鍵值對結構儲存在intent對象當中,intent對象通過調用方法putextras() 和 getextras()來存儲和擷取extra 

c)        extra是以bundle對象的形式來儲存的,bundle對象提供了一系列put和get方法來設定、提取相應鍵值資訊。 

d)        在intent類中同樣為android系統應用的一些extra的鍵值定義了靜态字元串常量。 

6.         flag 

決定intent目标元件的因素: 

n         在顯式intent消息中,決定目标元件的唯一要素就是元件名稱(不用再定義其他intent内容) 

n         而隐式intent消息中,由于沒有目标元件名稱,是以必須由android系統幫助應用程式尋找與intent請求意圖最比對的元件。 

n         隐式intent消息中目标元件具體選擇方法是:android将intent的請求内容和一個叫做intentfilter的過濾器比較,intentfilter中包含系統中所有可能的待選元件。如果intentfilter中某一個元件比對隐式intent請求内容,那麼android就選擇該元件作為該隐式intent的目标元件。 

intenfilter 

       應用程式的元件為了告訴android自己能響應、處理哪些隐式intent請求,可以聲明一個甚至多個intentfilter。

       每個intentfilter描述該元件所能響應intent請求的能力 —— 元件希望接收什麼類型的請求行為,什麼類型的請求資料。 

       隐式intent和intentfilter進行比較時的三要素:action、data、category。 

       一個隐式intent請求要能夠傳遞給目标元件,必需通過以上三個方面的檢查。如果任何一方面不比對,android都不會将該隐式intent傳遞給目标元件。 

       <intent-filter> 

              <action android:name=””/> 

              <category android:name=””/> 

              <data android:type=”” android:scheme=”” android:authority=”” android:path=””/> 

       </intent-filter> 

1.         動作測試 

a)         一條 <intent-filter> 中至少應該包含一個<action>, 否則任何intent請求都不能和該<intent-filter> 比對。 

b)        如果intentfilter 中沒有包含任何actino類型,那麼無論什麼intent請求都無法和這條intentfilter比對。 

c)        如果intent請求中沒有設定action類型,那麼隻要intentfilter中包含有action類型,這個intent請求将順利通過intentfilter的測試。 

2.         類别測試 

a)         隻有當intent請求中所有的category與元件中的某一個intentfilter的category完全比對,才會讓該intent請求通過測試,intentfilter中的多餘category聲明并不會導緻比對失敗。 

b)        一個沒有指定任何類别的intentfilter僅僅隻會比對沒有設定類别的intent請求。 

3.         資料測試 

a)         <data>元素指定了希望接受的intent請求的資料uri和資料類型:uri被分成三部分類進行比對,scheme、authority和 path. 

b)        使用 setdata設定的intent請求的uri資料類型和scheme,必須與intentfilter中指定的一緻 

若intentfilter中還指定了authority或path,他們也需要相比對才會通過測試。 

轉載至:http://blog.csdn.net/crazyjeff_liu/article/details/5545806