本篇内容介绍了“如何使用Binder类”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
服务端定义接口
定义aidl文件,放在src目录下
实现编译aidl后的内部类stub
Android SDK 工具会基于您的 .aidl 文件,使用 Java 编程语言生成接口。此接口拥有一个名为 Stub 的内部抽象类,用于扩展 Binder 类并实现 AIDL 接口中的方法。您必须扩展 Stub 类并实现这些方法。
向客户端公开接口
实现 Service 并重写 onBind(),从而返回 Stub 类的实现。
客户端使用
使用bindService()
再src目录包含该aidl文件,为客户端提供使用adil权限
注意: 调用是同步的,如果服务耗时需要再子线程调用,需要考虑线程安全
传递类
目前只能传递基本类型数据,传递对象类型需要model类实现Parcelable
调用方始终捕获DeadObjectException异常
DeadObjectException
// IRemoteService.aidl
package com.example.android
// Declare any non-default types here with import statements
/** Example service interface */
internal interface IRemoteService {
/** Request the process ID of this service, to do evil things with it. */
val pid:Int
/** Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
fun basicTypes(anInt:Int, aLong:Long, aBoolean:Boolean, aFloat:Float,
aDouble:Double, aString:String)
}
编译后生成
IRemoteService extends Binder implements IMyService{
class Stub extends android.os.Binder implements IMyService{
// 客户端拿到Binder获得一个Proxy代理对象
private static class Proxy implements IMyService{
}
}
}
// 向客户端公开接口
class RemoteService : Service() {
override fun onCreate() {
super.onCreate()
}
override fun onBind(intent: Intent): IBinder {
// Return the interface
return binder
}
// 实现stub
private val binder = object : IRemoteService.Stub() {
override fun getPid(): Int {
return Process.myPid()
}
override fun basicTypes(
anInt: Int,
aLong: Long,
aBoolean: Boolean,
aFloat: Float,
aDouble: Double,
aString: String
) {
// Does nothing
}
}
}
var iRemoteService: IRemoteService? = null
val mConnection = object : ServiceConnection {
// Called when the connection with the service is established
override fun onServiceConnected(className: ComponentName, service: IBinder) {
// Following the example above for an AIDL interface,
// this gets an instance of the IRemoteInterface, which we can use to call on the service
iRemoteService = IRemoteService.Stub.asInterface(service)
}
// Called when the connection with the service disconnects unexpectedly
override fun onServiceDisconnected(className: ComponentName) {
Log.e(TAG, "Service has unexpectedly disconnected")
iRemoteService = null
}
}
1、扩展binder类,常规service写法。非夸进程,用于后台服务处理 2、Messenger处理跨进程。特点是不需要考虑多线程安全,它是通过handler维护的messenger会创建所有请求的队列。使用简单 3、aidl,跨进程需要考虑多线程问题。设计相对复杂
// messenger服务创建
/** Command to the service to display a message */
private const val MSG_SAY_HELLO = 1
class MessengerService : Service() {
/**
* Target we publish for clients to send messages to IncomingHandler.
*/
private lateinit var mMessenger: Messenger
/**
* Handler of incoming messages from clients.
*/
internal class IncomingHandler(
context: Context,
private val applicationContext: Context = context.applicationContext
) : Handler() {
override fun handleMessage(msg: Message) {
when (msg.what) {
MSG_SAY_HELLO ->
Toast.makeText(applicationContext, "hello!", Toast.LENGTH_SHORT).show()
else -> super.handleMessage(msg)
}
}
}
/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
override fun onBind(intent: Intent): IBinder? {
Toast.makeText(applicationContext, "binding", Toast.LENGTH_SHORT).show()
mMessenger = Messenger(IncomingHandler(this))
return mMessenger.binder
}
}
“如何使用Binder类”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/3336230/blog/5016001