本篇內容介紹了“如何使用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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。