本文将详细介绍如何在Android中使用Kotlin实现AIDL(Android Interface Definition Language),并提供多种优化方案。
一、基础实现
1. 创建AIDL文件
在src/main/aidl/com/example/myapplication/
目录下创建:
IMyAidlInterface.aidl
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
aidl
package com.example.myapplication;
interface IMyAidlCallback {
void onDataChanged(in MyData data);
void onError(int errorCode, String message);
}
MyData.aidl
aidl
package com.example.myapplication;
parcelable MyData;
2. 实现Parcelable数据类
kotlin
@Parcelize
data class MyData(
val id: Int,
val name: String,
val timestamp: Long,
val processed: Boolean = false
) : Parcelable
确保在build.gradle
中添加:
gradle
plugins {
id 'kotlin-parcelize'
}
二、服务端实现
1. AIDL服务实现
kotlin
class MyAidlService : Service() {
private val binder = object : IMyAidlInterface.Stub() {
private val callbackList = RemoteCallbackList<IMyAidlCallback>()
override fun getVersion(): Int = BuildConfig.AIDL_VERSION
override fun add(a: Int, b: Int): Int = a + b
override 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配置
xml
<service
android:name=".MyAidlService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.myapplication.MyAidlService"/>
</intent-filter>
</service>
<permission
android:name="com.example.myapp.PERMISSION_AIDL"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.myapp.PERMISSION_AIDL" />
三、客户端实现
1. 服务连接管理器
kotlin
class AIDLServiceConnector(
private val context: Context,
private val packageName: String,
private val action: String
) {
private var _service: IMyAidlInterface? = null
val service: IMyAidlInterface? get() = _service
private 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 = null
onDisconnectedListeners.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中使用
kotlin
class MainActivity : AppCompatActivity() {
private lateinit var serviceConnector: AIDLServiceConnector
private 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. 性能监控实现
kotlin
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() - startTime
callStats.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: Double
get() = if (successCount > 0) totalDuration.toDouble() / successCount else 0.0
}
// ... 其他服务实现
}
2. 批量操作优化
kotlin
interface IMyAidlInterface {
// 单个操作
void processItem(in MyData item);
// 批量操作
void processItems(in List<MyData> items);
// 流式操作
void startStreaming();
void sendStreamItem(in MyData item);
void endStreaming();
}
3. 版本兼容处理
kotlin
interface IMyAidlInterface {
/**
* 获取AIDL接口版本
*/
int getVersion();
/**
* V1功能 - 基础操作
*/
void basicOperation();
/**
* V2功能 - 高级操作
*/
void advancedOperation() = 0; // 默认实现保持向后兼容
}
五、最佳实践总结
-
线程管理:
- 默认在Binder线程池执行
- 耗时操作应明确说明
- 客户端使用协程封装异步调用
-
回调管理:
- 必须使用RemoteCallbackList
- 处理回调进程死亡情况
- UI更新切回主线程
-
连接管理:
- 封装ServiceConnection
- 结合Lifecycle自动管理
- 提供重试机制
-
安全性:
- 添加权限验证
- 使用签名级保护
- 验证调用方身份
-
性能优化:
- 批量数据传输
- 监控方法调用性能
- 减少跨进程调用次数
-
兼容性:
- 接口版本控制
- 默认方法实现
- 优雅降级策略
通过以上实现和优化方案,可以构建出高效、稳定且易维护的AIDL通信架构。