Verwenden Sie Kotlin Coroutines, um das Einfädeln zu handhaben
Der Grund, warum der Code abstürzt, liegt darin, dass Bitmap
versucht wird, auf dem Code zu erstellen, der Main Thread
nicht zulässig ist, da dies zu ANR- Fehlern (Android Not Responding) führen kann.
Verwendete Konzepte
Implementierung
Code
1. Erstellen Sie Bitmap
in einem anderen Thread als dem Main Thread
.
In diesem Beispiel mit Kotlin Coroutines wird die Funktion in dem Dispatchers.IO
Thread ausgeführt, der für CPU-basierte Operationen vorgesehen ist. Der Funktion wird suspend
eine Coroutine- Syntax vorangestellt .
Bonus - Nachdem das Bitmap
erstellt wurde, wird es auch zu einem komprimiert, ByteArray
sodass es über ein Intent
später in diesem vollständigen Beispiel beschriebenes übergeben werden kann .
Repository.kt
suspend fun bitmapToByteArray(url: String) = withContext(Dispatchers.IO) {
MutableLiveData<Lce<ContentResult.ContentBitmap>>().apply {
postValue(Lce.Loading())
postValue(Lce.Content(ContentResult.ContentBitmap(
ByteArrayOutputStream().apply {
try {
BitmapFactory.decodeStream(URL(url).openConnection().apply {
doInput = true
connect()
}.getInputStream())
} catch (e: IOException) {
postValue(Lce.Error(ContentResult.ContentBitmap(ByteArray(0), "bitmapToByteArray error or null - ${e.localizedMessage}")))
null
}?.compress(CompressFormat.JPEG, BITMAP_COMPRESSION_QUALITY, this)
}.toByteArray(), "")))
}
}
ViewModel.kt
private fun bitmapToByteArray(url: String) = liveData {
emitSource(switchMap(repository.bitmapToByteArray(url)) { lce ->
when (lce) {
is Lce.Loading -> liveData {}
is Lce.Content -> liveData {
emit(Event(ContentResult.ContentBitmap(lce.packet.image, lce.packet.errorMessage)))
}
is Lce.Error -> liveData {
Crashlytics.log(Log.WARN, LOG_TAG,
"bitmapToByteArray error or null - ${lce.packet.errorMessage}")
}
}
})
}
Bonus - ByteArray
Zurück konvertieren zu Bitmap
.
Utils.kt
fun ByteArray.byteArrayToBitmap(context: Context) =
run {
BitmapFactory.decodeByteArray(this, BITMAP_OFFSET, size).run {
if (this != null) this
else AppCompatResources.getDrawable(context, ic_coinverse_48dp)?.toBitmap()
}
}