Android AIDL相關

Android AIDL相關

前言

Android系統中的進程之間不能共享內存,因此,需要提供一些機制在不同進程之間進行數據通信。

AIDL

全稱(Android Interface Definition Langague)

三種類型

AIDL

  • IPC(Inter-Process Communication,進程間通信),多線程,多個應用程序。

Binder

  • 只有IPC(Inter-Process Communication,進程間通信),沒有多線程,多個應用程序。

Messenger

  • 只有IPC(Inter-Process Communication,進程間通信),沒有多線程。

實現步驟

  1. 創建.aidl文件

    • 跟創建一個接口文件一樣創建.aidl文件。
    • Eclipse編譯後會放在gen目錄下。
    • Android Studio直接創建AIDL目錄,跟java目錄同級,直接創建AIDL文件。
    • Android Studio默認不編譯,需要編譯後纔會在Debug目錄下顯示出來。
  2. 實現接口(Implement the interface)

    • 創建一個繼承Service的類,裏面創建一個IBinder來實現Aidl.Stub裏面的方法的IBinder類型的變量。
  3. 共享接口給客戶端(Expose the interface to clients)

    • 將onBind方法返回的IBinder設置成定義的IBinder變量。
  4. 客戶端那裏同樣創建一個.aidl文件,同樣的包名。

  5. 客戶端綁定Service,使用Intent顯示Intent啓動,在5.0以後不支持隱式調用。
    Intent intent = new Intent();
    // 新版本5.0必須顯式Intent啓動綁定服務
    intent.setcomponent(new ComponetName("包名","包名.類名");
  1. 客戶端綁定Service,
    bindService(intent, conn, Context.BIND_AUTO_CREATE);
  2. 客戶端創建ServiceConnection變量,實現接口。
    private ServiceConnection conn = new ServiceConnection(){
        // 綁定服務的時候
        @Overrive
        public void onServiceConnected(ComponentName name, IBinder service){
            // 拿到遠程服務
            iImoocAidl = IImoocAidl.Stub.asInterface(service);
        }

        // 斷開服務的時候
        @Overrive
        public void onServiceDisconnected(ComponentName name){
            iImoocAidl = null;
        }
    }
  1. 服務端的AndroidManifest.xml文件中添加service,需要添加name,exported,enabled,process。
  2. 客戶端使用接口定義的方法。

注意

  • 更新aidl文件的內容要,要卸載後再運行,纔有用。
  • 除了默認的類型外,都需要導包。
  • 不支持short是因爲序列化添加不了short類型。

AIDL支持的數據類型

基本的數據類型(byte,int,long,char,boolean,float,double,不支持short)

String,CharSequence

List,Map(必須是支持的類型,也就是不支持short,需要設置in或out或inout屬性in List<String> aList)

Parcelable(需要設置in或out或inout屬性)

  1. 服務端創建實現Parcelable的實體類,如Person,創建構造方法、get、set方法,並且重寫未實現的方法。

  2. writeToParcel(Parcel dest, int flags)方法裏面寫入數據。

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }
  1. 創建CREATOR變量,在createFromParcel(Parcel source)方法裏面返回new Person(source)。
    public static final Creator<Person> CREATOR = new Creator<Person>() {

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }

        @Override
        public Person createFromParcel(Parcel source) {
            return new Person(source);
        }
    };
  1. 創建相應的構造方法,並且按順序讀取數據。
    public Person(Parcel source) {
        // 按順序
        this.name = source.readString();
        this.age = source.readInt();
    }
  1. 創建實體類對應的aidl文件,如Person.aidl。parcelable Person;

  2. 在主aidl文件內import對應的實體類,並且創建對應的方法,Parcelable也要設置in或out或inout屬性。

import com.example.aidlservice.Person;

interface AidlTestInterface {
    List<Person> add(in Person person);
}
  1. 設置Service。
    private ArrayList<Person> persons;

    @Override
    public IBinder onBind(Intent intent) {
        persons = new ArrayList<Person>();
        return iBinder;
    }

    private AidlTestInterface.Stub iBinder = new Stub() {

        @Override
        public List<Person> add(Person person) throws RemoteException {
            persons.add(person);
            return persons;
        }
    };
  1. 將對應的實體類文件,實體類aidl文件,主aidl文件複製到客戶端,包名必須一致。

  2. 客戶端調用對應的方法。

AIDL原理

這裏寫圖片描述
* Stub.asInterface(Ibinder)訪問的是Proxy。
* Proxy通過發送code請求給Stub裏面的OnTransact方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章