AIDL 的使用
- 创建 aidl 接口
- 创建 Person 对象,并实现 Parcelable 接口,Person 类可以放在 adil 目录下也可以放在 java 目录下,放在 aidl 目录下需要修改 buid.gradle 文件,否则找不到 Person 类,修改如下
android {
...
sourceSets{
main{
java {
// 指定 sourceSets
srcDirs "src/main/java","src/main/aidl"
}
}
}
}
- 创建 Person.aidl,可能会出现
// Perso.aidl
package com.lixuanlin.aidldemo;
// 注意 parcelable 是小写
parcelable Person;
- 修改 IDemonInterface.aidl
// IDemoInterface.aidl
package com.lixuanlin.aidldemo;
// 需要手动 import
import com.lixuanlin.aidldemo.Person;
// Declare any non-default types here with import statements
interface IDemoInterface {
void add(in Person person);
List<Person> get();
}
- 手动触发编译后,会生成 IDemoInterface.java 文件,结构如下,后面我讲详解介绍该类
public interface IDemoInterface extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements com.lixuanlin.aidldemo.IDemoInterface {
...
private static class Proxy implements com.lixuanlin.aidldemo.IDemoInterface {
...
}
...
}
public void add(com.lixuanlin.aidldemo.Person person) throws android.os.RemoteException;
public java.util.List<com.lixuanlin.aidldemo.Person> get() throws android.os.RemoteException;
}
- 创建 Service,实现 IDemoInterface.Stub 接口
class RemoteService : Service() {
override fun onBind(p0: Intent?): IBinder? {
return RemoteBinder()
}
inner class RemoteBinder : IDemoInterface.Stub() {
private val persons = ArrayList<Person>()
override fun add(person: Person?) {
person?.run {
persons.add(this)
}
}
override fun get(): ArrayList<Person> {
return persons
}
}
}
- 注册 Service
//指定进程名
<service android:name=".RemoteService" android:process=":remote"/>
- 绑定服务,并调用方法
class MainActivity : AppCompatActivity() {
var demoInterface: IDemoInterface? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent(this, RemoteService::class.java)
// 绑定服务
bindService(intent, object : ServiceConnection {
override fun onServiceDisconnected(p0: ComponentName?) {
demoInterface = null
}
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
// 获取接口
demoInterface = IDemoInterface.Stub.asInterface(p1)
}
}, BIND_AUTO_CREATE)
}
fun add(view: View) {
// 方法调用
val person = Person()
demoInterface?.add(person)
}
fun get(view: View) {
// 方法调用
demoInterface?.get()
}
}
源码分析
/*
* 客户端调用 transact() 方法后,服务端 onTransact() 方法会得到执行
*/
package com.lixuanlin.aidldemo;
public interface IDemoInterface extends android.os.IInterface {
/**
* 代表服务端
*/
public static abstract class Stub extends android.os.Binder implements com.lixuanlin.aidldemo.IDemoInterface {
private static final java.lang.String DESCRIPTOR = "com.lixuanlin.aidldemo.IDemoInterface";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.lixuanlin.aidldemo.IDemoInterface interface,
* generating a proxy if needed.
*/
public static com.lixuanlin.aidldemo.IDemoInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.lixuanlin.aidldemo.IDemoInterface))) {
// 未跨进程
return ((com.lixuanlin.aidldemo.IDemoInterface) iin);
}
// 跨进程
return new com.lixuanlin.aidldemo.IDemoInterface.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
java.lang.String descriptor = DESCRIPTOR;
// 根据 code 区分不同的方法调用
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
case TRANSACTION_add: {
data.enforceInterface(descriptor);
com.lixuanlin.aidldemo.Person _arg0;
if ((0 != data.readInt())) {
_arg0 = com.lixuanlin.aidldemo.Person.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
this.add(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_get: {
data.enforceInterface(descriptor);
java.util.List<com.lixuanlin.aidldemo.Person> _result = this.get();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}
/*
* 代表客户端
*/
private static class Proxy implements com.lixuanlin.aidldemo.IDemoInterface {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public void add(com.lixuanlin.aidldemo.Person person) throws android.os.RemoteException {
// 打包客户端需要传递的数据
android.os.Parcel _data = android.os.Parcel.obtain();
// 服务端处理后会通过 _reply 返回数据
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((person != null)) {
_data.writeInt(1);
person.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
// 跨进程操作,同步情况下会挂起
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public java.util.List<com.lixuanlin.aidldemo.Person> get() throws android.os.RemoteException {
// 打包客户端需要传递的数据
android.os.Parcel _data = android.os.Parcel.obtain();
// 服务端处理后会通过 _reply 返回数据
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List<com.lixuanlin.aidldemo.Person> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
// 跨进程操作,同步情况下会挂起
mRemote.transact(Stub.TRANSACTION_get, _data, _reply, 0);
_reply.readException();
_result = _reply.createTypedArrayList(com.lixuanlin.aidldemo.Person.CREATOR);
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_get = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void add(com.lixuanlin.aidldemo.Person person) throws android.os.RemoteException;
public java.util.List<com.lixuanlin.aidldemo.Person> get() throws android.os.RemoteException;
}
下篇文章将会介绍 transact 方法是怎么进行跨进程操作