上一篇文章介绍了 IPC跨进程通信之Messager(双向通信)
Messenger
是系统对aidl
一个轻量封装, 方便使用, 但是有一定局限性.
本文介绍直接介绍aidl
的使用, 让跨进程通信就跟本地调用一样爽.
准备
- 定义调用接口
- 创建相应的自定义数据Bean
用系统自带的菜单, 创建AIDL
文件, 并写上自己的接口定义.
你也可以直接创建File
后缀名为aidl
,没毛病;
需要注意的点
自定义的数据类型, 需要手动import xxx.xxx
, 系统不会自动导入.
参数类型还可以使用in
out
inout
标识.
需要注意的点
自定义的数据类, 需要在aidl
文件夹中, 创建对应的aidl
文件, 并且包名
和类名
需要完全一致.
服务端编写
class RemoteService : Service() {
/*用来和客户端通信的回调*/
var callback: ICallback? = null
private fun sendText(what: Int, text: String) {
callback?.callback("服务端回调:", MsgBean(text))
}
val myAidlInterface = object : IMyAidlInterface.Stub() {
override fun addCallback(callback: ICallback?) {
[email protected] = callback
}
override fun sendMsg(msg: MsgBean?): Int {
sendText(200, msg?.message ?: "empty")
return 200
}
override fun getMsg(flag: Int): MsgBean {
return MsgBean("getMsg 测试_flag:$flag")
}
}
override fun onBind(p0: Intent?): IBinder {
return myAidlInterface //直接返回成员对象
}
}
相较于Messenger
方式, 服务端的代码简洁了很多.
客户端编写
class MainActivity : AppCompatActivity() {
//声明对象
var myAidlInterface: IMyAidlInterface? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val remoteServiceIntent = Intent(this, RemoteService::class.java)
val remoteCon = object : ServiceConnection {
override fun onServiceDisconnected(p0: ComponentName?) {
L.e("call: onServiceDisconnected -> $p0")
showText("onServiceDisconnected_${p0}")
myAidlInterface = null
}
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
L.e("call: onServiceConnected -> $p0 $p1")
showText("onServiceConnected_${p0}")
//需要通过asInterface的方式,创建对象
myAidlInterface = IMyAidlInterface.Stub.asInterface(p1)
sendText(1, "客户端连接成功...")
}
}
findViewById<View>(R.id.bind).setOnClickListener {
bindService(remoteServiceIntent, remoteCon, Service.BIND_AUTO_CREATE)
}
}
private fun sendText(what: Int, text: String) {
myAidlInterface?.let {
//直接调用对象的方法进行通信,即可.
it.addCallback(object : ICallback.Stub() {
override fun callback(str: String?, msg: MsgBean?) {
showText("callback 回调:$str $msg")
}
})
val sendMsg = it.sendMsg(MsgBean("${what}_${text}"))
L.e("call: sendText -> 返回值:$sendMsg ${it.getMsg(404)}")
}
}
}
不要忘了在AndroidManifest.xml声明:
<service
android:name=".RemoteService"
android:process=":remote"/>
源码地址: https://github.com/angcyo/IPC_AIDL
也许你还想学习更多, 来我的群吧, 我写代码的能力, 远大于写文章的能力:
联系作者
请使用QQ扫码加群, 小伙伴们都在等着你哦!
关注我的公众号, 每天都能一起玩耍哦!