android的元件、Intent及設計思想

desaco發表於2016-02-01

> BroadcastReceiver元件:

Android總結篇系列:Android廣播機制(全域性廣播的Local廣播)-- http://www.cnblogs.com/lwbqqyumidi/p/4168017.html
廣播作為Android元件間的通訊方式,可以使用的場景如下:
1.同一app內部的同一元件內的訊息通訊(單個或多個執行緒之間);
2.同一app內部的不同元件之間的訊息通訊(單個程式);
3.同一app具有多個程式的不同元件之間的訊息通訊;
4.不同app之間的元件之間訊息通訊;
5.Android系統在特定情況下與App之間的訊息通訊。

從實現原理看上,Android中的廣播使用了觀察者模式,基於訊息的釋出/訂閱事件模型。因此,從實現的角度來看,Android中的廣播將廣播的傳送者和接受者極大程度上解耦,使得系統能夠方便整合,更易擴充套件。具體實現流程要點粗略概括如下:
1.廣播接收者BroadcastReceiver通過Binder機制向AMS(Activity Manager Service)進行註冊;
2.廣播傳送者通過binder機制向AMS傳送廣播;
3.AMS查詢符合相應條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播傳送到BroadcastReceiver(一般情況下是Activity)相應的訊息迴圈佇列中;
4.訊息迴圈執行拿到此廣播,回撥BroadcastReceiver中的onReceive()方法。

LocalBroadcastManager是support v4包裡提供的一個元件,它只負責程式內傳送廣播和接收訊息,它的優點如下:
  廣播訊息只在程式內傳送,不會造成資料洩露
  只接收程式內的廣播訊息,不會有廣播方面的安全問題
  比全域性的廣播效率更高

Android 內建了很多系統級別的廣播,通過監聽這些廣播可以得到相關的系統狀態資訊。例如:
  系統啟動完成
  開啟、關閉飛航模式
  電量低
  記憶體不足
  網路變化

根據廣播的傳送方式,可以將其分為以下幾種型別:
1.Normal Broadcast:普通廣播
2.System Broadcast: 系統廣播
3.Ordered broadcast:有序廣播
4.Sticky Broadcast:粘性廣播(在 android 5.0/api 21中deprecated,不再推薦使用,相應的還有粘性有序廣播,同樣已經deprecated)
5.Local Broadcast:App應用內廣播

同Android API版本中廣播機制相關API重要變遷
  1).Android5.0/API level 21開始粘滯廣播和有序粘滯廣播過期,以後不再建議使用;
  2).”靜態註冊的廣播接收器即使app已經退出,主要有相應的廣播發出,依然可以接收到,但此種描述自Android 3.1開始有可能不再成立“

  Android 3.1開始系統在Intent與廣播相關的flag增加了引數,分別是FLAG_INCLUDE_STOPPED_PACKAGES和FLAG_EXCLUDE_STOPPED_PACKAGES。
  FLAG_INCLUDE_STOPPED_PACKAGES:包含已經停止的包(停止:即包所在的程式已經退出)
  FLAG_EXCLUDE_STOPPED_PACKAGES:不包含已經停止的包

主要原因如下:
  自Android3.1開始,系統本身則增加了對所有app當前是否處於執行狀態的跟蹤。在傳送廣播時,不管是什麼廣播型別,系統預設直接增加了值為FLAG_EXCLUDE_STOPPED_PACKAGES的flag,導致即使是靜態註冊的廣播接收器,對於其所在程式已經退出的app,同樣無法接收到廣播。
  詳情參加Android官方文件:http://developer.android.com/about/versions/android-3.1.html#launchcontrols

  注1:對於動態註冊型別的BroadcastReceiver,由於此註冊和取消註冊實在其他元件(如Activity)中進行,因此,不受此改變影響。
  注2:在3.1以前,相信不少app可能通過靜態註冊方式監聽各種系統廣播,以此進行一些業務上的處理(如即時app已經退出,仍然能接收到,可以啟動service等..),3.1後,靜態註冊接受廣播方式的改變,將直接導致此類方案不再可行。於是,通過將Service與App本身設定成不同的程式已經成為實現此類需求的可行替代方案。   

--------------------------------------------------------------------------

Android應用層:

     > 整個Android系統,實際主要目的,就是打造一個功能共享的世界。功能共享最重要的互動,於是Android創造出一種Intent和IntentFilter配合的低耦合的互動模型,Intent只是一種描述要完成什麼工作跨程式的結構體,而最終如何解析這些Intent並完成其響應,是由IntentFilter來進行換算,最終是由使用者來決定如何完成。而在Intent這種超級互動訊息之上,Android進一步把應用程式的實現邏輯拆分成多種特殊的實現:

1. Activity:帶顯示與互動能力的部分
2. Service:不帶顯示與互動能力的部分
3. Content Provider:在功能互動之外,提供資料互動能力的部分

4. Broadcast Receiver:用來處理廣播互動的部分

> Activity

  Android的解決之道,則是將傳統意義上的應用程式,細化成一個個完成某項功能的部分,這種功能部分,在Android世界裡被稱為Activity。

  我們Application概念必須被弱化,我們不能有main函式入口(如果系統執行依賴main作入口,則不能實現Activity之間互相呼叫了,所有的Activity執行之前,必須先通過main入口來初始化環境)。出於這樣的設計,所以Application必須只是一個容器,將各種不同的Activity實現包裝起來載入到系統裡。

  一是Intent是一種能夠實現跨程式呼叫的資訊傳遞機制,二是Intent在訊息傳遞上又很靈活,有一定的動態性。Intent不光服務於Activity之間的呼叫,還會用於一些不直接與介面打交道的邏輯實現部分,比如我們後面將提到的Service,Broadcast Receiver,以及 Notification。

> 光有Activity與Intent,並不是Android應用程式程式設計時的全部。應用程式除了有人機互動介面之外,有可能還需要使用到一些不直接與人互動而在後臺長期執行操作;我們還需要有某種機制,能夠提供資料共享,並且在資料共享時能使用統一的訪問機制;最後,我們可能還需要處理以廣播方式傳送的訊息,廣播與Intent不同之處在於一到多的方式傳播,同時訊息只在某個時間段內有效。事實上,我們的Android程式設計,是被包裝成四個不同的型別,同時通過Intent將這些類包裝起來,以解決我們上面提到的,在編寫圖形應用程式裡可能遇到的問題的:
l   Intent: 全域性性的、鬆散的訊息傳遞機制
l   Activity:帶圖形介面的,可以與使用者進行互動的邏輯實現。

> Service
l   Service:  不帶圖形介面的,不直接與使用者互動的程式碼。一般會被用於在後臺做些什麼事情,比如監聽網路、下載、拷貝檔案等。(這可能是一般的Android工程師覺得沒有必要實現的部分,筆者在講解Android應用程式相關的課程時,就常有問及,Actiivity會進入到後臺,然後有可能被殺死掉,這樣的問題如何解決?實際上Activity只解決互動,需要在後臺時還需要繼續執行的程式碼,需要用Service來實現。只自己可訪問的Service,可以使用簡單的本地Service,而需要提供給別的程式來訪問的情況下,我們需要通過AIDL編寫Remote Service。Service的實現,我們在後臺再詳細說明,因為Android系統的核心Framework,本身就是由大量這樣的Remove Service來組成的。)
> Content Provider

   Content Provider:  提供資料層共享,以CRUD(Create Read Update Delete)方式進行資料訪問來統一化資料讀寫指口一種模型。如果使用了Sqlite做後臺的資料支援(實際上相當於應用程式MVC模型裡的Model部分被Sqlite延展開來),我們可以通過ContentProvider來各系統內的其他部分提供資料來源,當然系統本身也給我們提供了大量這樣的ContentProvider,像Setting裡的設定的值、聯絡列表、多媒體檔案掃描結果等。(這種資料層上的共享機制,也是應用程式程式設計上需要加強的技巧之一,因為有了Content Provider,我們則有可能使用Cursor式進行訪問,這時我們就可以使用CursorAdapter來自動化地處理資料來源。)
> Broadcast Receiver

Broadcast Receiver:處理廣播類訊息的監聽器,從而可以給應用程式提供廣播式的資訊處理,同時也提供系統訊息的廣播式分發。比如,Android會將一些系統事件廣播出來,像電話振鈴、電量狀態變化、網路狀態變化等,我們需要能夠處理這樣的事件,電話振鈴時我們寫的多媒體播放器就應該靜音、電量過低時需要儲存狀態等。對我們應用程式而言,廣播方式也是一種很好的通訊機制,我們不需要寫一個迴圈通知所有的Activity、Service我們狀態發生了改變,而只需要發一個廣播,則所有關心這一事件的部分都可以收到。

>所謂的Android程式設計,就是要通過編寫一個個的Activity、Service、Content Provider、Broadcast Receiver實現,通過功能上的共享與資料上的共享進一步豐富使用者可用的功能。當使用者可以通過Market或自己下載取得我們封裝到.apk檔案裡的實現之後,這些功能就會無縫地被Intent整合到了一起。

相關文章