1. 程式人生 > >Android程序間通訊的幾種方式

Android程序間通訊的幾種方式

定義多程序

Android應用中使用多程序只有一個辦法(用NDK的fork來做除外),就是在AndroidManifest.xml中宣告元件時,用android:process屬性來指定。

不知定process屬性,則預設執行在主程序中,主程序名字為包名。

android:process = package:remote,將執行在package:remote程序中,屬於全域性程序,其他具有相同shareUID與簽名的APP可以跑在這個程序中。

android:process = :remote ,將執行在預設包名:remote程序中,而且是APP的私有程序,不允許其他APP的元件來訪問。

多程序引發的問題

靜態成員和單例失效:每個程序保持各自的靜態成員和單例,相互獨立。

執行緒同步機制失效:每個程序有自己的執行緒鎖。

SharedPreferences可靠性下降:不支援併發寫,會出現髒資料。

Application多次建立:不同程序跑在不同虛擬機器,每個虛擬機器啟動會建立自己的Application,自定義Application時生命週期會混亂。

綜上,不同程序擁有各自獨立的虛擬機器,Application,記憶體空間,由此引發一系列問題。

 程序間通訊

Bundle/Intent傳遞資料:

可傳遞基本型別,String,實現了Serializable或Parcellable介面的資料結構。Serializable是Java的序列化方法,Parcellable是Android的序列化方法,前者程式碼量少(僅一句),但I/O開銷較大,一般用於輸出到磁碟或網絡卡;後者實現程式碼多,效率高,一般使用者記憶體間序列化和反序列化傳輸。

檔案共享:

對同一個檔案先後寫讀,從而實現傳輸,Linux機制下,可以對檔案併發寫,所以要注意同步。順便一提,Windows下不支援併發讀或寫。

Messenger:

Messenger是基於AIDL實現的,服務端(被動方)提供一個Service來處理客戶端(主動方)連線,維護一個Handler來建立Messenger,在onBind時返回Messenger的binder。

雙方用Messenger來發送資料,用Handler來處理資料。Messenger處理資料依靠Handler,所以是序列的,也就是說,Handler接到多個message時,就要排隊依次處理。

AIDL:

AIDL通過定義服務端暴露的介面,以提供給客戶端來呼叫,AIDL使伺服器可以並行處理,而Messenger封裝了AIDL之後只能序列執行,所以Messenger一般用作訊息傳遞。

通過編寫aidl檔案來設計想要暴露的介面,編譯後會自動生成響應的java檔案,伺服器將介面的具體實現寫在Stub中,用iBinder物件傳遞給客戶端,客戶端bindService的時候,用asInterface的形式將iBinder還原成介面,再呼叫其中的方法。

ContentProvider:

系統四大元件之一,底層也是Binder實現,主要用來為其他APP提供資料,可以說天生就是為程序通訊而生的。自己實現一個ContentProvider需要實現6個方法,其中onCreate是主執行緒中回撥的,其他方法是執行在Binder之中的。自定義的ContentProvider註冊時要提供authorities屬性,應用需要訪問的時候將屬性包裝成Uri.parse("content://authorities")。還可以設定permission,readPermission,writePermission來設定許可權。 ContentProvider有query,delete,insert等方法,看起來貌似是一個數據庫管理類,但其實可以用檔案,記憶體資料等等一切來充當資料來源,query返回的是一個Cursor,可以自定義繼承AbstractCursor的類來實現。

Socket:

學過計算機網路的對Socket不陌生,所以不需要詳細講述。只需要注意,Android不允許在主執行緒中請求網路,而且請求網路必須要注意宣告相應的permission。然後,在伺服器中定義ServerSocket來監聽埠,客戶端使用Socket來請求埠,連通後就可以進行通訊。