一、场景
公司项目里用了很多的独立进程的服务与其他进程之间存在了很多跨进程的通信。之前有很长一段时间没有实际去做跨进程通信 AIDL了,查阅了一些资料和文章看了些 Demo 把温习的心路历程介绍一下。
工具
Android studio
小米手机Android11(api 30)
模拟器手机Android8 (api 26)
为什么要准备两个手机,因为这里Android高版本的aidl使用有点坑的地方,需要做兼容处理,后面会讲到原因。
二、创建aidl的服务端 AIDLService(单独进程)
先创建aidl的服务端,因为正常情况下一个APP就是一个进程
新建一个服务,目前这个服务还是空类,因为需要等待aidl的创建好和aidl编译生成的新类,我们才能进一步去完善这个service。
package com.kang.aidlservice
import android.app.Service
import android.content.Intent
import android.os.IBinder
class KtvService:Service() {
override fun onBind(p0: Intent?): IBinder? {//这里参数变量显示p0是因为没下载对应sdk源码
return null
}
}
在清单文件中注册
<service
android:name=".KtvService"
android:enabled="true"
android:exported="true" >
<intent-filter>
<!--添加了一个唯一的action,供客户端隐式启动service-->
<action android:name="com.kang.aidlservice.KtvService"/>
</intent-filter>
</service>
三、在服务端创建aidl文件
1、在main右键--->New--->Directory--->选择aidl
2、新建aidl文件:
右键刚刚新建的aidl目录---》New--->AIDL--->AIDL File--->输入新建的aidl文件名
默认的aidl文件内容
我们修改后的aidl文件内容
之后就make project或者Rebuild project一下,等待编译。
编译成功之后,会在app目录下的build生成一个IKtvController.java的文件。
我们看看这个文件里面生成的内容,我们需要用到那个继承了Binder的类,因为Binder这是IPC的原理,进程之间通信就是用到的Binder机制。
3、使用上面生成的内容,完善刚刚创建的KtvService.kt类
package com.kang.aidlservice
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Log
class KtvService : Service() {
companion object {
private const val TAG = "binkang"
}
override fun onCreate() {
super.onCreate()
Log.i(TAG, "onCreate: ")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.i(TAG, "onStartCommand: ")
return super.onStartCommand(intent, flags, startId)
}
override fun onBind(p0: Intent?): IBinder? {
return KtvBinder()
}
//内部类KtvBinder,实现了aidl文件生成的Stub类
inner class KtvBinder : IKtvController.Stub() {
override fun setPause(pause: String?) {
Log.i(TAG, "setPause: $pause