Android 進程間通訊 AIDL詳解

最近項目有進程間通訊的需求,我使用的是IPC通訊的方式,這是Android中很傳統的一種進程間通訊的方式,在這裏分享給你們。javascript


進程間通訊意義

咱們爲何要使用進程間通訊。我說一個場景,好比咱們有兩個App,其中一個App(名字爲A),有受權登錄,咱們還有一個App(名字爲B)多是A的附屬App,或者同期產品,咱們但願有相同的帳號,也就是A登錄了,B就自動登陸了。那麼B在進入的時候須要從A中拿登錄信息,好比姓名性別,暱稱等。這時候就涉及到進程間通訊了。或者B中須要一些加密算法,咱們不想在B中暴露,能夠把值傳給A,而後A計算完再傳遞回來。
固然還有其它場景,這裏再也不贅述了。java

創建個工程

首先咱們固然要創建一個工程,最普通的工程就能夠。android

服務端App

這個工程中的第一個module服務端module,也就是上面提到的A app,內容提供的app
咱們在src/main中創建一個aidl文件夾:算法


右鍵點擊aidl文件夾,new一個aidl文件:

在裏面創建一個文件,好比咱們想獲取用戶信息:app

interface IPeople {
    /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */
     String getName();
     String getSex();
}複製代碼

而後rebuild一下工程,這時,會在build文件夾下生成一個文件ide


這個文件就是aidl生成的對應的接口文件,沒有這個文件,咱們以後在引用接口的時候會報錯。你不用給它轉移地方,放在這就好了。
而後咱們寫一個服務Service,提供數據:

public class AidlService extends Service{
    private PeopleBinder peopleBinder;
    @Override
    public void onCreate() {
        super.onCreate();
            peopleBinder = new  PeopleBinder();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return peopleBinder;
    }

    public class PeopleBinder extends IPeople.Stub {


        @Override
        public String getName() throws RemoteException {
            return "deep";
        }

        @Override
        public String getSex() throws RemoteException {
            return "man";
        }
    }
}複製代碼

其中PeopleBinder是進程間傳遞數據的媒介,若是你想傳一個數據類,那麼這個數據類必定要序列化。PeopleBinder實現的接口,就是剛纔咱們生成的那個文件中的接口。因此必定要等aidl接口文件生成咱們再去寫這個類。
而後將Service註冊在AndroidManifest中,注意要加一個action,方便客戶端App啓動:佈局

<service android:name=".AidlService">
            <intent-filter> <action android:name="deep.testaidl.AidlService"/> </intent-filter> </service>複製代碼

要注意app要安裝到手機上啊,不然後面怎麼獲取……學習

客戶端App

咱們新建一個module,這個module就是客戶端App,也就是咱們上文中提到的B App,內容索取者。
用一樣的方式創建一個aidl文件,這個aidl文件要與上面的同樣,且路徑也要同樣,如圖所示:ui


能夠看到路徑同樣,文件名同樣,固然內容也同樣。
這樣才能保證協議一致。而後仍是rebuild一下。生成對應的接口文件。
而後咱們在Activity中,隨便寫一個佈局(這個很少說了,與本文主旨無關),有個按鈕,有個顯示就行。
而後開始獲取用戶資料了,首先,咱們須要定義一個協議接口,也就是你獲取用戶資料的接口:

private IPeople people;//協議接口複製代碼

接着須要創建一個服務鏈接,與服務端App剛寫的那個Service進行鏈接通訊:加密

private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            people = IPeople.Stub.asInterface(service);//鏈接創建成功,讀取數據
            try {

               textView.setText("name ="+people.getName()+" sex="+people.getSex());
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            people = null;

        }
    };複製代碼

剛纔不是寫了一個按鈕嗎,添加一個點擊事件,打開服務端寫好的Service,進行通訊:

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setAction("deep.testaidl.AidlService");
                intent.setPackage("deep.testaidl");
                bindService(intent,conn, Service.BIND_AUTO_CREATE);
            }
        });複製代碼

因爲咱們剛纔在服務鏈接的回調中,將用戶信息設置到了textview上,這樣就能夠顯示出來了。
好了,這樣一次通訊就完成了,是否是沒有想象的複雜。

總結

這種進程間通訊的方式仍是比較傳統的,用的也比較多,瞭解一下對於之後的學習頗有幫助,若有其它問題能夠關注個人公衆號留言給我,我會第一時間回覆。
更多的開發知識,能夠關注個人公衆號:

相關文章
相關標籤/搜索