安卓AIDL进程间通信使用
练习aidl使用并记录一些心得, 写的尽量简单易懂, 也是参考了一些资料, 详细可以查看demo
效果图
AIDL是什么
Android官方推出了AIDL(
Android Interface Definition Language
) [Android接口定义语言]
Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
- 所以,为了使其他的应用程序也可以访问本应用程序提供的服务。
- Android应用程序组件中的3个
Activity
、BroadcastReceiver
和ContentProvider
)都可以进行跨进程访问,另外一个Android应用程序组件Service
同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL服务
Binder是什么
Binder
的出现是用来解决进程间通信(IPC)的。Binder实现了IBinder接口,IBinder是远程对象的基本接口,是为高性能而设计的轻量级远程调用机制的核心部分。但它不仅用于远程调用,也用于进程内调用。这个接口定义了与远程对象交互的协议。不要直接实现这个接口,而应该从Binder派生。
- 所以,是一个互相传递数据的接口
AIDL使用流程
- 创建服务端
- 创建客户端
- 客户端连接到服务端
- 发送/接收数据
使用注意事项
- 文件后缀必须为
.aidl
, 在执行build
后会自动生成.java
文件 ,其中会自动生成一个stub
抽象类 - 声明对象的时候实现
Parcelable
接口 -
in
对应writeToParcel()
方法,out
对应readFromParcel()
- Service需要声明外部可以访问
android:exported="true"
- 包名一定要引入正确, 手动
import
需要的类 - AIDL是可以处理多线程访问的请求的,要保证线程安全添加关键字
synchronized
部分代码
简单的一个例子:
服务端: 一个购买服务记录买的东西
客户端: 添加/查询/删除商品
- 服务端ShoppingService
private val shoppingManager = object : ShoppingManager.Stub() {
override fun addGood(good: Good?) {
synchronized(this) {}
}
override fun getGoods(): ArrayList<Good> {
synchronized(this) {}
}
override fun delGood(good: Good?) {
synchronized(this) {}
}
}
override fun onBind(intent: Intent?): IBinder? {
Log.e(TAG, String.format("执行onBind() ,intent = %s", intent.toString()))
return shoppingManager
}
- 客户端MyClientDemo
//创建连接
private val serviceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
shoppingManager = ShoppingManager.Stub.asInterface(service)
//连接后,可以调用服务端的 shoppingManager.xxx方法
}
override fun onServiceDisconnected(name: ComponentName) {}
}
//连接
val intent = Intent()
intent.setPackage("com.guoqi.myserverdemo") //需要设置包名
intent.action = "test_aidl"
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
//断开
unbindService(serviceConnection)
查看Demo