Verwenden Sie Kotlin Coroutines, um das Einfädeln zu handhaben
Der Grund, warum der Code abstürzt, liegt darin, dass Bitmapversucht wird, auf dem Code zu erstellen, der Main Threadnicht zulässig ist, da dies zu ANR- Fehlern (Android Not Responding) führen kann.
Verwendete Konzepte
Implementierung
Code
1. Erstellen Sie Bitmapin einem anderen Thread als dem Main Thread.
In diesem Beispiel mit Kotlin Coroutines wird die Funktion in dem Dispatchers.IOThread ausgeführt, der für CPU-basierte Operationen vorgesehen ist. Der Funktion wird suspendeine Coroutine- Syntax vorangestellt .
Bonus - Nachdem das Bitmaperstellt wurde, wird es auch zu einem komprimiert, ByteArraysodass es über ein Intentspä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 - ByteArrayZurü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()
}
}