1. 程式人生 > >Android多程序通訊

Android多程序通訊

原文來自:https://juejin.im/post/5aa08cb3f265da23766ad734   本人僅供學習筆記,如有侵權,請告知,我會刪除!

一、Android 中的多程序

1、定義:

首先,程序一般指一個執行單元,在移動裝置上就是一個程式或應用,我們在Android中所說的多程序(IPC)一般指一個應用包含多個程序。之所以要使用多程序有兩方面原因:某些模組由於特殊的需求要執行在單獨的程序;增加應用可用的記憶體空間。

2、開啟多程序

Android中開啟多執行緒只有一種方法,就是在AndroidManifest.xml中註冊Service、Activity、Receiver、ContentProvider時指定

android:process屬性,例如:

<service
    android:name=".MyService"
    android:process=":remote">
</service>

<activity
    android:name=".MyActivity"
    android:process="com.shh.ipctest.remote2">
</activity>


我們為MyServiceMyActivity指定的android:process屬性值有所不同,它們的區別如下:

  • :remote:以:開頭是一種簡寫,系統會在當前程序名前附件當前包名,完整的程序名為:com.shh.ipctest:remote
    ,同時以:開頭的程序屬於當前應用的私有程序,其它應用的元件不能和它跑在同一程序。
  • com.shh.ipctest.remote2:這是完整的命名方式,不會附加包名,其它應用如果和該程序的ShareUID簽名相同,則可以和它跑在同一個程序,實現資料共享。

3、多程序引發的問題

開啟多程序雖簡單,但會引發如下問題,必須引起注意。

  • 靜態成員和單例模式失效
  • 執行緒同步機制失效
  • SharedPreferences 可靠性降低
  • Application 被多次建立

對於前兩個問題,可以這麼理解,在Android中,系統會為每個應用或程序分配獨立的虛擬機器,不同的虛擬機器自然佔有不同的記憶體地址空間,所以同一個類的物件會產生不同的副本,導致共享資料失敗,必然也不能實現執行緒的同步。

由於SharedPreferences底層採用讀寫XML的檔案的方式實現,多程序併發的的讀寫很可能導致資料異常。

Application被多次建立和前兩個問題類似,系統在分配多個虛擬機器時相當於把同一個應用重新啟動多次,必然會導致 Application 多次被建立,為了防止在 Application中出現無用的重複初始化,可使用程序名來做過濾,只讓指定程序的才進行全域性初始:


public class MyApplication extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        String processName = "com.shh.ipctest";
        if (getPackageName().equals(processName)){
            // do some init
        }
    }

4、Android中的多程序通訊方式

Android中支援的多程序通訊方式主要有以下幾種,它們之間各有優缺點,可根據使用場景選擇選擇:

  • AIDL:功能強大,支援程序間一對多的實時併發通訊,並可實現 RPC (遠端過程呼叫)。
  • Messenger:支援一對多的序列實時通訊, AIDL 的簡化版本。
  • Bundle:四大元件的程序通訊方式,只能傳輸 Bundle 支援的資料型別。
  • ContentProvider:強大的資料來源訪問支援,主要支援 CRUD 操作,一對多的程序間資料共享,例如我們的應用訪問系統的通訊錄資料。
  • BroadcastReceiver:即廣播,但只能單向通訊,接收者只能被動的接收訊息。
  • 檔案共享:在非高併發情況下共享簡單的資料。
  • Socket:通過網路傳輸資料。

這裡我們主要討論四大元件中Service在多程序通訊中的使用,這就涉及到了 AIDLMessenger這兩種多程序通訊方式,接下來重點看這兩種 IPC 方式。

二、AIDL

AIDL 的意思是 Android 介面定義語言,使用AIDL進行程序間通訊需要定義服務端客戶端,其中客戶端和服務端可以在同一應用也可以在不同應用。這裡我們服務端可以看做是圖書館,為客戶端提供近期新書查詢、圖書捐贈、新書通知的服務。

三、Binder

在 AIDL 的例子中,客戶端之所以能和服務端通訊,主要依靠系統提供的Binder類實現,它實現了IBinder介面,我們在前邊的例子已經用到了Binder類,例如在服務端的 Service 中建立了一個Binder物件並在onBind()中返回:

四、Messenger

Messenger 是一種輕量級的多程序通訊方式,它是在 AIDL 的基礎上封裝而成的,可以看做是 AIDL 的簡化版,支援一對多的序列實時通訊,一次只處理一個請求,不存在併發的問題。和 AIDL 的使用類似,但要簡單的多,同樣需要實現服務端和客戶端。