部分文檔資料采用了郭林文章
進(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ù):
- 基本數(shù)據(jù)類型
- String和CharSequence
- List 接口(會(huì)自動(dòng)將List接口轉(zhuǎn)為 ArrayList),且集合的每個(gè)元素都必須能夠被 AIDL 支持
- Map 接口(會(huì)自動(dòng)將 Map 接口轉(zhuǎn)為 HashMap),且每個(gè)元素的 key 和 value 都必須被 AIDL 支持
- Parcelable 的實(shí)現(xiàn)類
- AIDL 接口本身
AIDL 使用方法
-
創(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ò)的。
-
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; } } -
客戶端代碼片段
/** * @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); } } -
實(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ù)再講