本篇内容介绍了“如何使用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类”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。