1. 程式人生 > >Android跨程序通訊AIDL詳解(附原始碼)

Android跨程序通訊AIDL詳解(附原始碼)

概述

AIDL:Android Interface Definition Language,即Android介面定義語言,記住,它是一門語言,設計它的目的就是為了實現跨程序通訊,我們知道Android的每一個程序都執行在獨立的記憶體中,程序之間程式碼是不能愉快的呼叫的,但是在我們開發中難免會有一些場景是需要實時進行程序間方法呼叫和資料傳遞。

AIDL支援的資料型別

  • JAVA的基本資料型別(byte、short、int、long、float、double、boolean、char)

  • String和Charsequence

  • List,只支援ArrayList,其中的物件必須序列化

  • Map、只支援HashMap,其中物件必須序列化

  • 實現android.os.Parcelable 介面的物件

  • AIDL自動生成的介面

AIDL實現步驟

第一步:建立工程

由於AIDL是程序間通訊,所以先要定義兩個工程,我們定義為:
客戶端:AIDLClientDmeo
服務端:AIDLServerDmeo (服務端需要實現Service服務)

建立工程很簡單,這裡忽略這個過程;

第二步:定義AIDL介面

image

通過Android Studio建立一個以.aidl結尾的檔案,為了實現2個程序能相互呼叫,定義2個aidl:IFirstAidlInterface.aidl和ICallbackInterface.aidl

    package com.ailian.study;

    interface IServerListener {
       void backByServer(String param);
    }


    package com.ailian.study;

    import com.ailian.study.IServerListener;//注意這邊需要手動引入

    interface IFirstAidlInterface {
        void callServer(String type,IServerListener callback);
}

定義AIDL介面注意點:

  • AIDL介面在相互通訊的兩個程序都要定義,而且檔案路徑和檔名都需要一致,這一點很重要,否則將無法進行通訊;
    image

第三步:編譯

在定義完AIDL介面後,需要先編譯工程,因為在編譯後IDE會自動為我們在app/build/generated/source/aidl/debug/目錄生成同名的JAVA檔案,不需要關注這個檔案是如何生成的,自動生成的檔案是readOnly的不可以修改,我們這裡不解釋裡面生成的內容;
image

第四步:AIDLServerDmeo實現Service

上面步驟中我們已經在2個工程中都定義好了AIDL介面,現在可以在Server端實現Service,並暴露出來讓其他程序bind;

    package com.ailian.study.aidlserverdemo;

    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;

    /**
     * Created by ailian on 2018/6/9/009.
     */

    public class AidlService extends Service {

        private AidlServiceSub mServiceStub;

        @Override
        public void onCreate() {
            super.onCreate();
            mServiceStub = new AidlServiceSub();
        }

        @Override
        public IBinder onBind(Intent intent) {
            /**
             * 這裡會返回一個binder物件,在Client獲取到這個物件
             */
            return mServiceStub;
        }

        @Override
        public boolean onUnbind(Intent intent) {
            return super.onUnbind(intent);
        }

    }

onBind方法中有個返回值IBinder物件,Client通過bindService通過介面可以獲取到這個IBinder物件,AidlServiceSub需要繼承IFirstAidlInterface自動生成的IFirstAidlInterface.Stub物件:

    package com.ailian.study.aidlserverdemo;

    import android.os.RemoteException;
    import android.util.Log;

    import com.ailian.study.IFirstAidlInterface;
    import com.ailian.study.IServerListener;

    /**
     * Created by ailian on 2018/6/9/330.
     */
    public class AidlServiceSub extends IFirstAidlInterface.Stub {

        @Override
        public void callServer(String type, IServerListener callback) throws RemoteException {
            Log.d("AidlServiceSub", "Client發過來的資訊:" + type);
            callback.backByServer("黃河黃河,我也是黃河");
        }
    }

第五步:AIDLServerDmeo實現Service

在AIDLServerDemo的AndroidManifest.xml中宣告第四步建立的Service

android:exported=”true” //執行其他APP啟動

android:process=”:remote”//執行在單獨的程序

//需要自定義一個action其他程序啟動該服務就通過這個aciton:

    <service
        android:name=".AidlService"
        android:exported="true"
        android:process=":remote">
        <intent-filter>
            <action android:name="android.ailian.aidl.test" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </service>

第六步:AIDLClientDmeo啟動Service

上面的五步後,Client端就可以通過bindService與Server端建立通訊通道了:

    Intent it = new Intent();
    it.setAction("android.ailian.aidl.test");
    it.setPackage("com.ailian.study.aidlserverdemo");
    bindService(it, mserviceConnection, BIND_AUTO_CREATE);

這裡有個mserviceConnection,是呼叫bindService的一個回撥

    ServiceConnection mserviceConnection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            /**
             * 繫結失敗的回撥
             */
            bindServiceTip.setText("服務繫結失敗,請重新繫結");
            clientContent.setText("");
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            /**
             * 繫結成功的回撥,這裡獲取到了IBinder物件,我們就是通過這個IBinder實現與Server進行通訊
             */
            bindServiceTip.setText("服務繫結成功,可以通訊了");
            clientContent.setText("");
            executeService = IFirstAidlInterface.Stub.asInterface(service);
        }
    };

搞定啦,我們來測試一下吧

驗證結果

我們將2個APP同時安裝在同一臺手機中

image

通過手機直接測試,測試成功可以相互通訊;

沒有原始碼的步驟講解都是耍流氓

image

附上原始碼下載地址,希望對您有所幫助: