Android AIDL教程

部分文檔資料采用了郭林文章

進(jìn)程間通訊方式

Android 進(jìn)程間通信有以下幾種方案可選

  • Bundle
  • file
  • aidl
  • ContentProvider
  • Network

AIDL 使用

AIDL 官方解釋:

AIDL(Android 接口定義語言)與您可能使用過的其他 IDL 類似。 您可以利用它定義客戶端與服務(wù)使用進(jìn)程間通信 (IPC) 進(jìn)行相互通信時(shí)都認(rèn)可的編程接口。 在 Android 上,一個(gè)進(jìn)程通常無法訪問另一個(gè)進(jìn)程的內(nèi)存。 盡管如此,進(jìn)程需要將其對(duì)象分解成操作系統(tǒng)能夠識(shí)別的原語,并將對(duì)象編組成跨越邊界的對(duì)象。 編寫執(zhí)行這一編組操作的代碼是一項(xiàng)繁瑣的工作,因此 Android 會(huì)使用 AIDL 來處理。

AIDL解釋:

aidl其實(shí)就是一個(gè)類似于socket的服務(wù),服務(wù)端服務(wù)所有的客戶端,服務(wù)端提供統(tǒng)一服務(wù),各個(gè)客戶端分別請(qǐng)求服務(wù)端獲取對(duì)應(yīng)的數(shù)據(jù),支持一對(duì)多。

支持?jǐn)?shù)據(jù):
  1. 基本數(shù)據(jù)類型
  2. String和CharSequence
  3. List 接口(會(huì)自動(dòng)將List接口轉(zhuǎn)為 ArrayList),且集合的每個(gè)元素都必須能夠被 AIDL 支持
  4. Map 接口(會(huì)自動(dòng)將 Map 接口轉(zhuǎn)為 HashMap),且每個(gè)元素的 key 和 value 都必須被 AIDL 支持
  5. Parcelable 的實(shí)現(xiàn)類
  6. AIDL 接口本身
AIDL 使用方法
  1. 創(chuàng)建AIDL接口

    // IMyService.aidl
    package com.ly.test;
    
    // Declare any non-default types here with import statements
    import com.ly.test.Student;
    
    interface IMyService {
    
        List<Student> getStudent();
        void setStudio(in Student student);
    }
    

    創(chuàng)建AIDL 注意事項(xiàng)

    • 使用 import 語句在此聲明任何非默認(rèn)類型,即自定義對(duì)象需要顯示的使用 import 導(dǎo)入進(jìn)來
    • 如果 AIDL 文件中使用了自定義的 parcelable 對(duì)象,那么必須新建一個(gè)和它同名的 AIDL 文件,如上面示例。
    • 除了基本類型數(shù)據(jù),其它類型的參數(shù)必須標(biāo)上方向:in、out、inout。in 表示輸入;out 表示輸出;inout 表示輸入輸出型的參數(shù),注意按需使用,因?yàn)?out 以及 inout 在底層實(shí)現(xiàn)是需要一定開銷的。
    • AIDL 接口僅支持方法,不支持靜態(tài)變量,也不支持普通的接口
    • AIDL 所有相關(guān)的類在另一個(gè)應(yīng)用使用的時(shí)候需要保證所有文件的路徑完全一致,因?yàn)榭邕M(jìn)程涉及到序列化和反序列化。假設(shè) A 進(jìn)程的 a 經(jīng)過序列化傳輸?shù)?B 進(jìn)程,卻在相同的文件路徑下找不到響應(yīng)的對(duì)象,這是會(huì)出錯(cuò)的。
  1. server 服務(wù)端代碼

    package com.ly.test;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.IInterface;
    import android.os.Parcel;
    import android.os.RemoteException;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * MyServer
     *
     * @author Francis
     * @date 2019-07-23
     */
    
    public class MyServer extends Service {
        private final List<Student> data = new ArrayList<>();
    
        private final IMyService.Stub mbinder = new IMyService.Stub() {
            @Override
            public List<Student> getStudent() throws RemoteException {
                return data;
            }
    
            @Override
            public void setStudio(Student student) throws RemoteException {
                data.add(student);
            }
        };
    
        @Override
        public void onCreate() {
            super.onCreate();
            data.add(new Student("小明", 12));
            data.add(new Student("小明", 13));
            data.add(new Student("小明", 14));
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return mbinder;
        }
    }
    
    
  2. 客戶端代碼片段

    
    /**
     * @author Francis
     */
    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = "MainActivity";
        private ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                IMyService sub = IMyService.Stub.asInterface(service);
                try {
                    List<Student> data = sub.getStudent();
                    for (Student student : data) {
                        Log.e(TAG, "onServiceConnected: "+student.toString() );
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
    
            @Override
            public void onBindingDied(ComponentName name) {
    
            }
    
            @Override
            public void onNullBinding(ComponentName name) {
    
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            postRequest(getWindow().getDecorView());
            bindService(new Intent(this, MyServer.class), connection, BIND_AUTO_CREATE);
        }
    }
    
  3. 實(shí)體類及AIDL文件

    /**
     * Student
     *
     * @author Francis
     * @date 2019-07-23
     */
    
    public class Student implements Parcelable {
    
        private String name;
        private int age;
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        protected Student(Parcel in) {
            name = in.readString();
            age = in.readInt();
        }
    
        public static final Creator<Student> CREATOR = new Creator<Student>() {
            @Override
            public Student createFromParcel(Parcel in) {
                return new Student(in);
            }
    
            @Override
            public Student[] newArray(int size) {
                return new Student[size];
            }
        };
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(name);
            dest.writeInt(age);
        }
    
        @NotNull
        @Override
        public String toString() {
            return "name=" + name + ",age=" + age;
        }
    }
    
    // Student.aidl
    package com.ly.aoptest;
    
    // Declare any non-default types here with import statements
    
    parcelable Student ;
    
    
    

即時(shí)通信的實(shí)現(xiàn)

后續(xù)再講

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容