0

I'm trying to use Glide to display thumbnails from the Google Photos library in a RecyclerView. In order to fetch images from this library, I must make two HTTP requests: first I must get the MediaItem from the id (I've already obtained a list of ids in a previous step), and second I must request the actual image from thumbnailUrl. This is the recommended process, as baseUrls expire after one hour so you aren't supposed to store them:

val googlePhotosThumbnailUrl = 
    App.googlePhotosService.getMediaItem(asset.googlePhotosId) // First HTTP request fetches MediaItem
        .run {
            val baseUrl = this.baseUrl
            val thumbnailUrl = "$baseUrl=w400-h400" // Appends the requested dimensions to the Url.
            thumbnailUrl // Second HTTP request fetches this URL
        }

The problem is that Glide's load() method doesn't appear to support chaining HTTP requests like what's shown above:

GlideApp.with(itemView.context)
    .asBitmap()
    .load(googlePhotosThumbnailUrl)
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .into(binding.imageViewLargeThumbnail)

The above code executes synchronously, so loading is incredibly slow. I've managed to fix this by using coroutines as shown below. But the problem with this is Glide doesn't cache any of the images, so if I scroll down and back up Glide refetches every image:

override fun bindAsset(asset: GooglePhotosAsset, position: Int) {
    this.asset = asset
    this.index = position

    // We set the loading animation here for Google Photos assets, since for those we need to fetch a mediaItem and then a baseUrl.
    // This forces us to perform the process in a coroutine, and Glide can't set the loading animation until the baseUrl is fetched.
    binding.imageViewLargeThumbnail.setImageResource(R.drawable.loading_animation)

    fragment.lifecycleScope.launch(Dispatchers.Default) {
        val googlePhotosThumbnailUrl = App.googlePhotosService.getMediaItem(asset.googlePhotosId) // First HTTP request fetches MediaItem
            .run {
                val baseUrl = this.baseUrl
                val thumbnailUrl = "$baseUrl=w400-h400" // Appends the requested dimensions to the Url.
                thumbnailUrl // Second HTTP request fetches this URL
            }

        withContext(Dispatchers.Main) {
            GlideApp.with(itemView.context)
                .asBitmap()
                .load(googlePhotosThumbnailUrl)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .fitCenter()
                .into(binding.imageViewLargeThumbnail)
        }
    }
}

The only potentially relevant answer I've found is this one, but it seems super complicated and outdated. Are there any better solutions?

Gavin Wright
  • 2,444
  • 2
  • 11
  • 31

0 Answers0