本文将详细介绍如何在Android中使用Kotlin实现AIDL(Android Interface Definition Language),并提供多种优化方案。
一、基础实现
1. 创建AIDL文件
在src/main/aidl/com/example/myapplication/
目录下创建:
IMyAidlInterface.aidl
package com.example.myapplication;interface IMyAidlInterface {int getVersion();int add(int a, int b);void registerListener(IMyAidlCallback callback);void unregisterListener(IMyAidlCallback callback);oneway void doSomethingAsync();
}
IMyAidlCallback.aidl
package com.example.myapplication;interface IMyAidlCallback {void onDataChanged(in MyData data);void onError(int errorCode, String message);
}
MyData.aidl
package com.example.myapplication;parcelable MyData;
2. 实现Parcelable数据类
@Parcelize
data class MyData(val id: Int,val name: String,val timestamp: Long,val processed: Boolean = false
) : Parcelable
确保在build.gradle
中添加:
plugins {id 'kotlin-parcelize'
}
二、服务端实现
1. AIDL服务实现
class MyAidlService : Service() {private val binder = object : IMyAidlInterface.Stub() {private val callbackList = RemoteCallbackList<IMyAidlCallback>()override fun getVersion(): Int = BuildConfig.AIDL_VERSIONoverride fun add(a: Int, b: Int): Int = a + boverride fun registerListener(callback: IMyAidlCallback?) {callback?.let { callbackList.register(it) }}override fun unregisterListener(callback: IMyAidlCallback?) {callback?.let { callbackList.unregister(it) }}override fun doSomethingAsync() {// 异步操作实现}private fun notifyCallbacks(data: MyData) {val count = callbackList.beginBroadcast()try {for (i in 0 until count) {try {callbackList.getBroadcastItem(i).onDataChanged(data)} catch (e: RemoteException) {Log.e("AIDL", "Callback failed", e)}}} finally {callbackList.finishBroadcast()}}}override fun onBind(intent: Intent): IBinder = binder
}
2. AndroidManifest.xml配置
<service android:name=".MyAidlService"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.example.myapplication.MyAidlService"/></intent-filter>
</service><permissionandroid:name="com.example.myapp.PERMISSION_AIDL"android:protectionLevel="signature" /><uses-permission android:name="com.example.myapp.PERMISSION_AIDL" />
三、客户端实现
1. 服务连接管理器
class AIDLServiceConnector(private val context: Context,private val packageName: String,private val action: String
) {private var _service: IMyAidlInterface? = nullval service: IMyAidlInterface? get() = _serviceprivate val connection = object : ServiceConnection {override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {_service = IMyAidlInterface.Stub.asInterface(binder)onConnectedListeners.forEach { it() }}override fun onServiceDisconnected(name: ComponentName?) {_service = nullonDisconnectedListeners.forEach { it() }}}private val onConnectedListeners = mutableListOf<() -> Unit>()private val onDisconnectedListeners = mutableListOf<() -> Unit>()fun bind() {val intent = Intent(action).setPackage(packageName)context.bindService(intent, connection, Context.BIND_AUTO_CREATE)}fun unbind() {context.unbindService(connection)_service = null}fun addOnConnectedListener(listener: () -> Unit) {onConnectedListeners.add(listener)}fun addOnDisconnectedListener(listener: () -> Unit) {onDisconnectedListeners.add(listener)}suspend fun <T> safeCall(block: (IMyAidlInterface) -> T): Result<T> {return try {val service = _service ?: return Result.failure(IllegalStateException("Service not bound"))Result.success(block(service))} catch (e: RemoteException) {Result.failure(IOException("AIDL communication failed", e))} catch (e: SecurityException) {Result.failure(SecurityException("Permission denied", e))}}
}
2. 在Activity/Fragment中使用
class MainActivity : AppCompatActivity() {private lateinit var serviceConnector: AIDLServiceConnectorprivate val callback = object : IMyAidlCallback.Stub() {override fun onDataChanged(data: MyData) {runOnUiThread {updateUI(data)}}override fun onError(errorCode: Int, message: String) {runOnUiThread {showError(message)}}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)serviceConnector = AIDLServiceConnector(this,"com.example.serviceapp","com.example.serviceapp.MyAidlService")serviceConnector.addOnConnectedListener {registerCallback()performInitialOperation()}lifecycle.addObserver(AIDLLifecycleObserver(serviceConnector))}private fun registerCallback() {viewModelScope.launch {serviceConnector.safeCall { service ->service.registerListener(callback)}}}private fun performInitialOperation() {viewModelScope.launch {when (val result = serviceConnector.safeCall { it.add(5, 3) }) {is Result.Success -> showResult(result.value)is Result.Failure -> showError(result.exception.message)}}}// ... UI更新方法
}class AIDLLifecycleObserver(private val connector: AIDLServiceConnector
) : LifecycleObserver {@OnLifecycleEvent(Lifecycle.Event.ON_START)fun onStart() {connector.bind()}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)fun onStop() {connector.unbind()}
}
四、高级优化方案
1. 性能监控实现
class MonitoredAIDLService : Service() {private val binder = object : IMyAidlInterface.Stub() {private val callStats = ConcurrentHashMap<String, CallStats>()override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean {val methodName = getTransactionName(code) ?: "unknown"val startTime = System.nanoTime()try {val result = super.onTransact(code, data, reply, flags)recordCallStats(methodName, startTime, true)return result} catch (e: Exception) {recordCallStats(methodName, startTime, false)throw e}}private fun recordCallStats(methodName: String, startTime: Long, success: Boolean) {val duration = System.nanoTime() - startTimecallStats.compute(methodName) { _, stats ->(stats ?: CallStats()).apply {totalCalls++if (success) {successCount++totalDuration += duration} else {failureCount++}}}}// ... 其他方法实现}data class CallStats(var totalCalls: Int = 0,var successCount: Int = 0,var failureCount: Int = 0,var totalDuration: Long = 0) {val averageDuration: Doubleget() = if (successCount > 0) totalDuration.toDouble() / successCount else 0.0}// ... 其他服务实现
}
2. 批量操作优化
interface IMyAidlInterface {// 单个操作void processItem(in MyData item);// 批量操作void processItems(in List<MyData> items);// 流式操作void startStreaming();void sendStreamItem(in MyData item);void endStreaming();
}
3. 版本兼容处理
interface IMyAidlInterface {/*** 获取AIDL接口版本*/int getVersion();/*** V1功能 - 基础操作*/void basicOperation();/*** V2功能 - 高级操作*/void advancedOperation() = 0; // 默认实现保持向后兼容
}
五、最佳实践总结
-
线程管理:
- 默认在Binder线程池执行
- 耗时操作应明确说明
- 客户端使用协程封装异步调用
-
回调管理:
- 必须使用RemoteCallbackList
- 处理回调进程死亡情况
- UI更新切回主线程
-
连接管理:
- 封装ServiceConnection
- 结合Lifecycle自动管理
- 提供重试机制
-
安全性:
- 添加权限验证
- 使用签名级保护
- 验证调用方身份
-
性能优化:
- 批量数据传输
- 监控方法调用性能
- 减少跨进程调用次数
-
兼容性:
- 接口版本控制
- 默认方法实现
- 优雅降级策略
通过以上实现和优化方案,可以构建出高效、稳定且易维护的AIDL通信架构。