Intereting Posts
Как присоединиться к двум RxJava2 Obvervables по ключу? Кнопка libgdx up down no effect Как установить вкладку BottomNavigationView по умолчанию в Kotlin? Pass listOf (mapOf (x, y, z)) как параметр в Kotlin Android Kotlin меняет свой массив на spinner на карту Ошибка: com.app.android.dagger.component.AppComponent (unscoped) может не ссылаться на привязки с привязкой: Комната с кинжалом в Котлине: Дао имеет значение null, при введении в класс Android SpeechRecognizer не запускается снова Получить загрузчик классов generics для разбора вложенного поля Parcelable generic Андроид anko предупреждение пользовательский макет currentFocus Как установить setOnItemClickListener для просмотра списка с помощью пользовательского адаптера Kotlin Критерии запроса для сопоставления 3 из 6 полей Каким образом можно создать и опубликовать библиотеку Kotlin, чтобы избежать многократного запуска? Как выполнить некоторый код, когда gradle строит тесты Должен ли я отказаться от подписки при использовании rxbinding?

CountDownLatch не освобождает поток

У меня есть метод, который загружает изображение из Firebase Storage. Он вызван в фоновом потоке, и мне нужно заблокировать его, пока изображение не будет загружено (чтобы избежать обратного ад). Вот код (в Котлине)

override fun fromNet(): Bitmap? { Log.wtf(TAG, "$name loading from firebase") var result: Bitmap? = null val lock = CountDownLatch(1) try { FirebaseStorage.getInstance().getReferenceFromUrl(FIRE_STORAGE).child(ctx.getKGL().famkey) .child(name).getBytes(524288L) .addOnFailureListener { Log.wtf(TAG, "$name load failure") lock.countDown() } .addOnSuccessListener { bytes -> Log.wtf(TAG, "$name loaded") val b = BitmapFactory.decodeByteArray(bytes, 0, bytes.size).scale(ctx.dip(64)) result = b lock.countDown() ctx.saveToCache(name, b) } .addOnCompleteListener { Log.wtf(TAG, "on complete") lock.countDown() } } catch (ignored: NullPointerException) { lock.countDown() } lock.await() return result } 

Но поток остается заблокированным навсегда

Logcat:

 A/MemberPhoto: xvd6z67gZfMCLG4c9mkGXKe9ML53 load failure A/MemberPhoto: on complete 

UPD: Может ли быть причиной, что код Firebase – это Java, а мой код – в Котлине?

Если вы хотите быть уверенным, что lock.await() не заставит ваш текущий поток ждать навсегда, вам нужно убедиться, что lock.countDown() вызывается тем, что происходит, поэтому здесь вы должны окружить с помощью try/finally блок кода ваших слушателей, чтобы вызвать lock.countDown() в блоке finally .

В противном случае с вашим текущим кодом, если, например, BitmapFactory.decodeByteArray(bytes, 0, bytes.size).scale(ctx.dip(64)) терпит неудачу, lock.countDown() никогда не будет вызван, который сделает lock.await() вызовов потоков lock.await() wait lock.await() ждать вечно.

Например, в случае успеха код вашего слушателя должен быть скорее:

 .addOnSuccessListener { bytes -> try { Log.wtf(TAG, "$name loaded") val b = BitmapFactory.decodeByteArray(bytes, 0, bytes.size).scale(ctx.dip(64)) result = b } finally { lock.countDown() } ctx.saveToCache(name, b) }