簡體   English   中英

Firebase addOnSuccessListener 回調運行上下文拋出`NetworkOnMainThreadException`

[英]Firebase addOnSuccessListener callback running context throws `NetworkOnMainThreadException`

假設我有一個存儲庫 class,它定義了一種從 Firebase 存儲中檢索圖像的方法,並定義了一個成功偵聽器,該偵聽器調用從視圖 model 定義的回調

fun getAdImg(imgId: String, callback: (stream: Bitmap?) -> Unit) {
        storage.child(FOLDER).child(imgId+EXTENSION).stream
            .addOnSuccessListener {
                callback(BitmapFactory.decodeStream(it.stream))
                Log.i(TAG, "getAdImg success")
            }
            .addOnCanceledListener {
                Log.e(TAG, "getAdImg canceled")
            }
            .addOnFailureListener {
                Log.e(TAG, "getAdImg failure")
            }

    }

定義回調並調用存儲庫的視圖 model 中的 function 如下

fun loadImage(imgId: String?) {
        imgId?.let { id ->
            if (_img.value == null) {
                viewModelScope.launch (context = IO) {
                    AdvertisementRepository.getInstance().getAdImg(id) { bitmap ->
                        _img.postValue(bitmap)
                    }
                }
            }
        }
    }

我有一些問題:

  • 由存儲庫addOnSuccessListener中的 addOnSuccessListener 定義的偵聽器的生命周期是什么?
  • 在監聽器中調用callback function 的 scope 是什么?
  • 當我嘗試運行此代碼時, BitmapFactory.decodeStream(it.stream)將拋出一個android.os.NetworkOnMainThreadException ,由於調用decodeStream function 的上下文,這似乎是一個異常

由存儲庫 class 中的 addOnSuccessListener 定義的偵聽器的生命周期是什么?

你在這里使用它的方式,它沒有生命周期。 回調將無限期持續。

在監聽器中調用回調 function 的 scope 是什么?

它沒有協程 scope。 只要結果准備好,就會在主線程上調用回調。

當我嘗試運行此代碼時, BitmapFactory.decodeStream(it.stream)將拋出一個 android.os.NetworkOnMainThreadException,由於調用 decodeStream function 的上下文,這似乎是一個異常

是的,因為回調是在主線程上調用的,並且 decodeStream 執行 I/O,所以如果啟用嚴格模式來檢測主線程上的 I/O,您會期望它會拋出異常。 這就是為什么 getStream() 的 API 文檔說:

通過 InputStream 在此 StorageReference 處異步下載 object。 應該在通過 addOnSuccessListener(Executor, OnSuccessListener) 注冊以在后台線程上運行的 OnSuccessListener 上讀取 InputStream

文檔建議您安排在使用 Executor 的主線程以外的線程上調用回調。 或者,您可以使用協程,但 API 不支持 Kotlin,因此您需要自行安排。 有一個庫可以幫助將任務轉換為協程使用。

https://github.com/Kotlin/kotlinx.coroutines/tree/master/integration/kotlinx-coroutines-play-services

暫無
暫無

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

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