CountDownLatch没有释放线程

我有一个方法,从Firebase存储加载图像。 它被称为后台线程,我需要阻止它,直到图像加载(以避免回调地狱)。 这里是代码(在Kotlin)

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,而我的代码是在Kotlin?

如果你想确保lock.await()不会使你当前的线程永远等待,你需要确保lock.countDown()被调用,无论发生什么事情,所以在这里你应该围绕一个try/finally块的代码你的监听器为了在finally块中调用lock.countDown()

除此之外,如果您的当前代码例如BitmapFactory.decodeByteArray(bytes, 0, bytes.size).scale(ctx.dip(64))失败, lock.countDown()永远不会被调用,这将使线程调用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) }