AIDL全称为Android Interface Definition Language(安卓接口定义语言),适用于不同应用的客户端进程通过 IPC 方式访问服务,以下例子为了方便将在一个App里定义Service为独立进程,恰巧我最近学习kotlin,所以用的是kotlin语法(不过大同小异~~)。在实现AIDL之前,要先理解绑定服务。
最终效果图

实现步骤
1.生成AIDL文件,成功之后会看到有AIDL文件夹

生成服务端的AIDL文件 ISer
interface ISer {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt,long aLong,boolean aBoolean,float aFloat,double aDouble,String aString);
void registerCallback(IServiceCallback cb);
void unregisterCallback(IServiceCallback cb);
}
其中这个方法是自动生成,不用可以删除
void basicTypes(int anInt,long aLong,boolean aBoolean,float aFloat,double aDouble,String aString);
这两个方法是自定义的注册与注销回调方法,IServiceCallback也是生成的AIDL
void registerCallback(IServiceCallback cb);
void unregisterCallback(IServiceCallback cb);
IServiceCallback用于回调监听到的数字
interface IServiceCallback {
void valueChanged(int value);
}


2.声明一个IBinder接口实例,并且在Service的onBind()方法中返回此实例
/**
* 服务端
*/
class RemoteService : Service() {
var mValue = 0
//控制IServiceCallback接口的注册和注销
val callbackList = RemoteCallbackList<IServiceCallback>()
//每隔一秒发送自增的值
private val handler = Handler(Handler.Callback {
if (it.what == Const.REPORT_MSG) {
val value = mValue++
val N = callbackList.beginBroadcast()
for (i in 0 until N) try {
callbackList.getBroadcastItem(i).valueChanged(value)//回调自增的值
} catch (e: RemoteException) {
e.printStackTrace()
}
callbackList.finishBroadcast()
it.target.run {
sendMessageDelayed(obtainMessage(Const.REPORT_MSG), (1 * 1000).toLong())
}
}
false
})
override fun onCreate() {
super.onCreate()
Const.log("Service onCreate")
handler.sendEmptyMessage(Const.REPORT_MSG)// 发送信息,开始自增
}
override fun onBind(intent: Intent): IBinder {
//返回IBinder实例
return binder
}
//ISer.Stub继承自Binder类
private val binder = object : ISer.Stub() {
override fun registerCallback(cb: IServiceCallback?) {
cb?.run { callbackList.register(this) }
}
override fun unregisterCallback(cb: IServiceCallback?) {
cb?.run { callbackList.unregister(this) }
}
override fun basicTypes(anInt: Int, aLong: Long, aBoolean: Boolean, aFloat: Float, aDouble: Double, aString: String?) {
}
}
override fun onDestroy() {
super.onDestroy()
Const.log("Service onDestroy")
//Service消毁的时候移除 RemoteCallbackList 里面的全部回调
callbackList.kill()
//移除 Handler 全部回调和消息
handler.removeCallbacksAndMessages(null)
}
}
3.客户端实现ServiceConnection
客户端在onServiceConnected() 回调中收到IBinder时,必须调用 yourServiceInterface(你的接口名).Stub.asInterface(service),以将返回的参数转换成 yourServiceInterface类型
var remoteService: ISer? = null
private val serviceConnection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName?) {
Const.log("Service has unexpectedly disconnected ")
remoteService = null
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
remoteService = ISer.Stub.asInterface(service) //转换成Iser接口
remoteService?.registerCallback(callback) //注册监听
Const.log(" onServiceConnected::${name?.className}::: ")
}
}
接口回调
val callback = object : IServiceCallback.Stub() {
override fun valueChanged(value: Int) {
clientHandler.run { sendMessage(obtainMessage(Const.BUMP_MSG, value, 0)) }
}
}
Handler更新TextView
val clientHandler = Handler(Handler.Callback {
when (it.what) {
Const.BUMP_MSG -> {
tv_service_count.text = "数字增量:${it.arg1} "
}
}
false
}
)
3.客户端绑定服务
调用bindService(), 传入ServiceConnection
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent(this, RemoteService::class.java)
btn_bind_server.setOnClickListener {
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
}
btn_unbind_server.setOnClickListener {
unbindService(serviceConnection)
}
}
至此,一个简单的AIDL例子就大概实现了,第一次po文,写得不好多多包涵。
网友评论