AIDL进程间通信
一、项目开启AIDL
在使用AIDL的模块下build.gradle
文件中添加以下代码
android {...buildFeatures {aidl true}
}
操作完需要rebuild
二、创建aidl服务接口
假设当前所需要的包名为com.jingluo.test_aidl
,那么aidl
就需要处于同样的路径下,即如下目录格式。假设服务接口文件为IModuleService
、IModuleCallback
。实现接口的文件为TestAIDLService
- main- aidl- com- jingluo- test_aidl- IModuleService.aidl- IModuleCallback.aidl- kotlin-com- jingluo- test_aidl- TestAIDLService.kt
aidl支持如下几种数据类型
- 基本数据类型:
boolean:布尔值(true 或 false)
byte:8 位有符号整数
char:16 位 Unicode 字符
double:64 位双精度浮点数
float:32 位单精度浮点数
int:32 位有符号整数
long:64 位有符号整数
short:16 位有符号整数 - Java 对象:
String:字符串
CharSequence:字符序列 - Bundle:
Bundle 类可以用于在进程间传递一组键值对的集合,类似于一个映射表。 - List 和 Map:
List:支持基本数据类型和支持 Parcelable 接口的对象类型的列表。
Map<K, V>:支持基本数据类型和支持 Parcelable 接口的对象类型的映射表。 - Parcelable:
自定义的类如果实现了 Parcelable 接口,也可以在 AIDL 中使用。这是一个用来序列化对象的接口,可以将对象数据从一个进程传递到另一个进程。 - Surface
- RemoteView
IModuleService.aidl
package com.jingluo.test_aidl;import android.view.Surface;
import com.jingluo.test_aidl.IModuleCallback;interface IModuleService {void handleMethod(String method);void registerCallback(IModuleCallback callback);
}
IModuleCallback.aidl
package com.jingluo.test_aidl;interface IModuleCallback {void onLoginCallback(int code, String msg);
}
操作完需要rebuild
三、aidl接口实现(服务端)
TestAIDLService.kt
...
import android.os.IBinder
import android.app.Service
import com.jingluo.test_aidl.IModuleCallback
import com.jingluo.test_aidl.IModuleService
...class TestAIDLService: Service() {private lateinit var context: Context// 按需实现,我这里主要是需要拿到Contextoverride fun onCreate() {super.onCreate()context = this}private var remoteCallback: IModuleCallback? = nullprivate val binder = object : IModuleService.Stub() {override fun handleMethod(method: String) {if (method == "loginResult") {// eg. remoteCallback?.onLoginCallback(0, "success")} else if (method == "login") {// 具体实现}}override fun registerCallback(callback: IModuleCallback) {remoteCallback = callback;DeviceManager.registerRemoteCallback(callback)}}override fun onBind(p0: Intent?): IBinder {return binder}
}
四、客户端使用
...
import com.jingluo.test_aidl.TestAIDLService
...class TestAIDLActivity: AppCompatActivity() {private var moduleService: IModuleService? = nullprivate val moduleCallback = object : IModuleCallback.Stub() {override fun onLoginCallback(code: Int, msg: String) {/// 相应处理}}private val mDeathRecipient: IBinder.DeathRecipient = object : IBinder.DeathRecipient {override fun binderDied() {// 解绑当前监听,重新启动服务moduleService?.asBinder()?.unlinkToDeath(this, 0)moduleService = null// 重新绑定服务bindService()}}private val connection: ServiceConnection = object : ServiceConnection {override fun onServiceConnected(name: ComponentName, service: IBinder) {moduleService = IModuleService.Stub.asInterface(service)moduleService?.registerCallback(moduleCallback)moduleService?.asBinder()?.linkToDeath(mDeathRecipient, 0)}override fun onServiceDisconnected(name: ComponentName) {moduleService = null}}private fun bindService() {val intent = Intent(context, TestAIDLService::class.java)context.bindService(intent, connection, Context.BIND_AUTO_CREATE)}
}
同时需要在AndroidManifest.xml
中进行声明该服务。注意android:process
必须设置,否则分进程不生效。
<application><service android:name=".TestAIDLService"android:process=":remote"android:enabled="true"android:exported="false" />
</application>