部分文档资料采用了郭林文章
进程间通讯方式
Android 进程间通信有以下几种方案可选
- Bundle
- file
- aidl
- ContentProvider
- Network
AIDL 使用
AIDL 官方解释:
AIDL(Android 接口定义语言)与您可能使用过的其他 IDL 类似。 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。 在 Android 上,一个进程通常无法访问另一个进程的内存。 尽管如此,进程需要将其对象分解成操作系统能够识别的原语,并将对象编组成跨越边界的对象。 编写执行这一编组操作的代码是一项繁琐的工作,因此 Android 会使用 AIDL 来处理。
AIDL解释:
aidl其实就是一个类似于socket的服务,服务端服务所有的客户端,服务端提供统一服务,各个客户端分别请求服务端获取对应的数据,支持一对多。
支持数据:
- 基本数据类型
- String和CharSequence
- List 接口(会自动将List接口转为 ArrayList),且集合的每个元素都必须能够被 AIDL 支持
- Map 接口(会自动将 Map 接口转为 HashMap),且每个元素的 key 和 value 都必须被 AIDL 支持
- Parcelable 的实现类
- AIDL 接口本身
AIDL 使用方法
-
创建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); }
创建AIDL 注意事项
- 使用 import 语句在此声明任何非默认类型,即自定义对象需要显示的使用 import 导入进来
- 如果 AIDL 文件中使用了自定义的 parcelable 对象,那么必须新建一个和它同名的 AIDL 文件,如上面示例。
- 除了基本类型数据,其它类型的参数必须标上方向:in、out、inout。in 表示输入;out 表示输出;inout 表示输入输出型的参数,注意按需使用,因为 out 以及 inout 在底层实现是需要一定开销的。
- AIDL 接口仅支持方法,不支持静态变量,也不支持普通的接口
- AIDL 所有相关的类在另一个应用使用的时候需要保证所有文件的路径完全一致,因为跨进程涉及到序列化和反序列化。假设 A 进程的 a 经过序列化传输到 B 进程,却在相同的文件路径下找不到响应的对象,这是会出错的。
-
server 服务端代码
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); } }
-
实体类及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 ;
即时通信的实现
后续再讲