https://kotlinlang.org logo
#coroutines
Title
# coroutines
n

Nikola Milovic

03/13/2021, 7:32 AM
Is this an okay approach to download images from an URL while saving them to local storage. It should happen in parallel and I need to await for all three images to return their URI before proceeding. I kinda dislike the
if (edgesUri.getCompleted() == null
null checks and the
labelUri.getCompleted()!!.path!!
. Any way to improve this?
Copy code
suspend fun saveImageToDB(networkImageModel: CBImageNetworkModel): Result<Long> {
        return withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
            try {       
                val edgesUri = this.async {
                    val urlEdges = URL(networkImageModel.edgesImageUrl)
                    return@async saveBitmapToAppStorage(urlEdges.openStream(), ImageType.EDGES)
                }
                val finalUri = this.async {
                    val urlFinal = URL(networkImageModel.finalImageUrl) 
                    return@async saveBitmapToAppStorage(urlFinal.openStream(), ImageType.FINAL)

                }
                val labelUri = this.async {
                    val urlLabels = URL(networkImageModel.labelsImageUrl)
                    return@async saveBitmapToAppStorage(urlLabels.openStream(), ImageType.LABELS)
                }

                awaitAll(edgesUri, finalUri, labelUri)

                if (edgesUri.getCompleted() == null || finalUri.getCompleted() == null || labelUri.getCompleted() == null) {
                     Result.failure<Long>(Exception("An image couldn't be saved"))
                }

                val image = CBImageDataModel(
                    labelsImageUri = labelUri.getCompleted()!!.path!!,
                    finalImageUri = finalUri.getCompleted()!!.path!!,
                    edgesImageUri = edgesUri.getCompleted()!!.path!!,
                )
                Result.success(db.imageDao().insertImage(image))
            } catch (e: Exception) {
                Timber.e(e)
                Result.failure(e)
            }
        }
o

Orhan Tozan

03/13/2021, 9:41 AM
Why can uri.getCompleted return null at that point? Also, no need for them all three uris to wait before inserting them. In the async, after getting the uri, just insert it immediately after
d

Dominaezzz

03/13/2021, 10:41 AM
Also, you don't need
awaitAll
. Just do
val edgesImage = edges.await()
for each image. That should tidy up your code a bit.
n

Nikola Milovic

03/13/2021, 11:14 AM
@Orhan Tozan Also, no need for them all three uris to wait before inserting them. In the async, after getting the uri, just insert it immediately after
What do you mean by this exactly? I need all three URI's before I insert my entity into db, right? @Dominaezzz thank you, that should improve the readiability a bit
o

Orhan Tozan

03/13/2021, 12:42 PM
Yes I misread the final insert. But why can getCompleted() be null?
n

Nikola Milovic

03/13/2021, 12:48 PM
Because if there was error I am returning null, either that or throwing errors
2 Views