当前位置: 首页 > news >正文

AIDL简单使用

一、AIDL基础

AIDL(Android Interface Definition Language) 是Android用于跨进程通信的接口定义语言,基于Binder机制实现。
核心流程:

  1. 定义接口(.aidl文件)
  2. 实现接口(服务端)
  3. 绑定服务(客户端)
  4. 跨进程调用

二、Demo

  1. 定义AIDL接口
    文件:ICalculator.aidl
// ICalculator.aidl  
package com.example.aidldemo;  interface ICalculator {  int add(int a, int b);  int subtract(int a, int b);  
}  
  1. 实现服务端
    CalculatorService.kt
class CalculatorService : Service() {  private val binder = object : ICalculator.Stub() {  override fun add(a: Int, b: Int): Int = a + b  override fun subtract(a: Int, b: Int): Int = a - b  }  override fun onBind(intent: Intent): IBinder = binder  
}  

AndroidManifest.xml

<service  android:name=".CalculatorService"  android:exported="true"  android:process=":remote"/>  

客户端绑定与调用
MainActivity.kt

class MainActivity : AppCompatActivity() {  private var calculator: ICalculator? = null  private val connection = object : ServiceConnection {  override fun onServiceConnected(name: ComponentName?, service: IBinder?) {  calculator = ICalculator.Stub.asInterface(service)  }  override fun onServiceDisconnected(name: ComponentName?) {  calculator = null  }  }  override fun onCreate(savedInstanceState: Bundle?) {  super.onCreate(savedInstanceState)  bindService(  Intent(this, CalculatorService::class.java),  connection,  Context.BIND_AUTO_CREATE  )  // 调用示例  btnAdd.setOnClickListener {  val result = calculator?.add(5, 3) // 输出8  Toast.makeText(this, "Result: $result", Toast.LENGTH_SHORT).show()  }  }  override fun onDestroy() {  unbindService(connection)  super.onDestroy()  }  
}  

三、传递自定义对象

  1. 定义Parcelable对象
    User.kt
@Parcelize  
data class User(val id: Int, val name: String) : Parcelable  
IUserManager.aidl
// IUserManager.aidl  
package com.example.aidldemo;  
import com.example.aidldemo.User;  interface IUserManager {  void addUser(in User user);  List<User> getUsers();  
}  
  1. 实现服务端
    UserManagerService.kt
class UserManagerService : Service() {  private val users = mutableListOf<User>()  private val binder = object : IUserManager.Stub() {  override fun addUser(user: User) {  users.add(user)  }  override fun getUsers(): MutableList<User> = users  }  override fun onBind(intent: Intent): IBinder = binder  
}  
  1. 客户端调用
val userManager = IUserManager.Stub.asInterface(service)  
userManager.addUser(User(1, "Alice"))  
val userList = userManager.users // 获取用户列表  

四、关键问题与解决方案

  1. 线程模型

    • 服务端方法默认运行在Binder线程池
    • 解决方案:
      override fun addUser(user: User) {  // 切换到主线程更新UI  Handler(Looper.getMainLooper()).post {  // 更新UI操作  }  
      }  
      
  2. 异常处理

try {  val result = calculator?.add(5, 3)  
} catch (e: RemoteException) {  Log.e("AIDL", "Remote call failed", e)  
}  
  1. 权限控制
    服务端验证权限:
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean {  val permission = checkCallingOrSelfPermission("com.example.PERMISSION")  if (permission != PackageManager.PERMISSION_GRANTED) {  throw SecurityException("Permission denied")  }  return super.onTransact(code, data, reply, flags)  
}  

五、性能优化技巧

批量数据传输:
// AIDL接口定义

void addUsers(in List<User> users); 

使用oneway非阻塞调用:

oneway void logEvent(in String event); 

对象池复用:

private val userPool = Pools.SynchronizedPool<User>(10)  fun getUser(): User = userPool.acquire() ?: User()  
fun recycleUser(user: User) = userPool.release(user)  

服务端断连处理

服务断开 → onServiceDisconnected/binderDied → 启动重连 → 指数退避重试
├─ 成功 → 重置重试计数
└─ 失败 → 提示用户

  1. 检测服务端断连
    通过 ServiceConnection 监听连接状态
private val serviceConnection = object : ServiceConnection {override fun onServiceConnected(name: ComponentName?, service: IBinder?) {// 绑定成功aidlService = IMyAidlInterface.Stub.asInterface(service)// 添加死亡监听(关键!)service?.linkToDeath(deathRecipient, 0)}override fun onServiceDisconnected(name: ComponentName?) {// 服务异常断开aidlService = nullscheduleReconnect() // 触发重连逻辑}
}// Binder 死亡监听(更底层)
private val deathRecipient = IBinder.DeathRecipient {runOnUiThread {Toast.makeText(this, "服务端进程终止,尝试重连...", Toast.LENGTH_SHORT).show()scheduleReconnect()}
}
通过 linkToDeath 监听 Binder 死亡
//更底层监听 Binder 对象存活状态:
private fun registerBinderDeathListener(binder: IBinder?) {binder?.linkToDeath(object : IBinder.DeathRecipient {override fun binderDied() {// Binder死亡(非主线程,需切线程处理)runOnUiThread {showToast("服务已断开,正在重连...")scheduleReconnect()}}}, 0) // flags 传0即可
}
  1. 自动重连策略
    指数退避重连
private var reconnectAttempts = 0
private val maxReconnectAttempts = 5
private val reconnectHandler = Handler(Looper.getMainLooper())private fun scheduleReconnect() {if (reconnectAttempts >= maxReconnectAttempts) {Log.w("AIDL", "超过最大重试次数,放弃重连")return}val delay = 2_000L * (reconnectAttempts + 1) // 2s, 4s, 8s...reconnectHandler.postDelayed({bindAidlService()reconnectAttempts++}, delay)
}private fun bindService() {val intent = Intent(this, CalculatorService::class.java)bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
}
http://www.dtcms.com/a/326695.html

相关文章:

  • 【接口自动化测试】---YAML、JSON Schema
  • 逐际动力开源运控 tron1-rl-isaacgym 解读与改进
  • VMD例程(Matlab 2021b可直接使用)
  • 从“目标烂尾”到“100%交付”:谷歌OKR追踪系统如何用“透明化+强问责”打造职场责任闭环
  • 小白入门指南:Edge SCDN 轻松上手
  • Dify 从入门到精通(第 28/100 篇):Dify 的多租户架构
  • 【学习嵌入式day-21-Linux编程-shell命令】
  • 第九篇:调试工具:Three.js Inspector使用
  • 武汉火影数字|VR大空间是什么?如何打造VR大空间项目
  • 【华为机试】648. 单词替换
  • SciChart图形库应用
  • 专题:2025人形机器人与服务机器人技术及市场报告|附130+份报告PDF汇总下载
  • TCGA数据集下载工具gdc-client下载慢解决方案
  • mysql参数调优之 innodb_buffer_pool_size和innodb_buffer_pool_instances (三)
  • Java AI生成长篇小说的实用
  • VirtualBox虚拟机网卡配置
  • NR,LTE基于CSI的PMI-RI码本选择
  • 【算法训练营Day23】贪心算法part1
  • nginx高新能web服务器
  • UVM验证—UVM 简述
  • 从0-1搭建webpack的前端工程化项目
  • MySQL杂项
  • OpenBMC中phosphor-dbus-interfaces深度解析:架构、原理与应用实践
  • 安装AI高性能推理框架llama.cpp
  • Untiy_SpriteShape
  • VSCode编辑器常用24款基础插件
  • QT QVersionNumber 比较版本号大小
  • 自主泊车算法
  • OFD一键转PDF格式,支持批量转换!
  • 客户端连接redis,redis如何配置