簡體   English   中英

如何正確等待 Android 服務綁定到活動

[英]How to properly wait for an Android Service to be bounded to an Activity

我正在開發一個應用程序,其中一旦對用戶可見,幾個 Activitis 就會綁定到一個服務。 在啟動期間,每個 Activity 需要:

  • 檢查服務的一些狀態標志,根據這些標志配置一些 UI 元素
  • 檢查是否啟用了引用在服務內部的適配器
  • 執行服務的一些功能

由於應用程序不應在后台獲取更新,因此我在 onStart() 綁定到服務並在 onStop() 取消綁定。 即有這樣的東西:

override fun onStart() {
    super.onStart()
    Intent(context, MyService::class.java).also { intent ->
        bindService(intent, serviceCallback, Context.BIND_AUTO_CREATE)
    }
}

現在我想在 onResume 中執行上面提到的操作。

override fun onResume() {
    super.onResume()
    // check flags
    // check adapter status
    // excute functions of service
}

問題是綁定到服務是異步的,我在 onResume() 中沒有對服務綁定器的有效引用。 因此,應用程序將因空指針異常而崩潰。

方法一:使用lateinit

我嘗試使用 lateinit 關鍵字解決這個問題。 即我定義對活頁夾的引用為

private lateinit var myBinder: MyService.LocalBinder

問題:我不能保證綁定器已初始化,因為它是異步的。 因此,應用程序將崩潰。

方法2:在while循環中等待回調

在我的服務回調中,我設置了一個標志,如下所示:

val serviceCallback = object : ServiceConnection {

    override fun onServiceConnected(className: ComponentName, service: IBinder) {
        myBinder = service as MyService.LocalBinder
        isServiceBounded = true
    }

    override fun onServiceDisconnected(arg0: ComponentName) {
        isServiceBounded = false
        myBinder = null
    }
}

然后在 onResume 中,我阻止Activity 直到標志為真

override fun onResume() {
    super.onResume()
    while(!isServiceBounded){
        // block and wait
    }
}

問題:也不行。 該應用程序將停止響應並崩潰。

方法 3:使用掛起函數和 Kotlin 協程

除非收到返回值,否則暫停的 function 將不會繼續。 這個,我可以用它來等待一個事件。 所以我嘗試了這樣的事情:

override fun onStart() {
    super.onStart()
    CoroutineScope(Dispatchers.Main).launch {
        bindServiceAndWait(this@Activityname)
    }
}

suspend fun bindServiceAndWait(context: Context): Boolean{
    Intent(context, MyService::class.java).also { intent ->
        bindService(intent, serviceCallback, Context.BIND_AUTO_CREATE)
    }
    return isServiceBounded // This is the flag from the callback
}

問題:這個暫停的 function 實際上並沒有等待回調。 它只返回 isServiceBounded 的當前值。

我在這里找到了一個類似的解決方案,但我不太了解這個解決方案,因為它有一個全局服務回調 (ServiceConnection) 以及暫停的 function 內部的一個本地服務回調。 另外,我不明白如何在這個提供的示例中解綁。

這樣做的正確方法是什么?

在調用onResume之前,您根本無法確保服務將受到限制。 為什么不引入標志isResumed ,將其設置在onResume中(在onPause中取消設置)並在下面的行檢查if (isResumed && isServiceBounded)... 是的,有可能isServiceBounded = falseonResume ,所以if檢查放在onServiceConnected

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM