Sharing Glide Images Instantly

Ashutosh Singh Tomar
Bobble Engineering
Published in
4 min readNov 5, 2020

Well, yes you read that correct. As an android developer we deal a lot with images loaded from the server or any API, mostly we display images in a list, or we might even display them on a page like UI, depends totally on your scenario.

Glide is quite a popular Android Library, used for Image Loading, this article isn’t about how to setup glide, rather it’s one step ahead.

If you wanna share the image that you just showed in the list, how would you do that?

A normal approach is first to make a network call to load all the images in the list, saving all the urls in a POJO/Model class, then on the click of the image or the share button, you read the url from the pojo and then you make another network call to download the image from the url, meanwhile the image is getting ready to be shared you show a progress bar.

Well, guess what, there is no need for making two separate network calls, all this could be done with just one network call, and your users would get an amazing experience as how instantly the images are shared on a single tap without any time wasted in showing the progress bar.

Here is a small glimpse of how things look on a 3g or slower network, here you see a list of gifs that can be shared from the keyboard.

Earlier it took more than 30 seconds to share the image on a 3g network after the images have already been shown to the user.

Here is how the onBindViewHolder of an Adapter usually looks

// Loading the image in the recycler viewif (gif.url != null) {
gifUrl=gif.url
Glide.with(mContext)
.asGif()
.load(gif.url)
.fitCenter()
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(gifHolder.gifImage)
}

// Handling clicks on the image
gifHolder.gifImage.setOnClickListener(View.OnClickListener { val gifs = mGif[gifHolder.adapterPosition]
mGifInterface!!.clickOnGif(gifs)
})

We load the image into the ImageView and set an OnClickListener, and then with the help of the interfaces, we handle the click event and download the image using the downloadGif function.

private fun downloadGif(url: String) {
progress_bar.visibility= View.VISIBLE
//Creating a file for the downloaded image val folderPath=SaveUtils.createDirAndGetPath(mContext, "resources", "folderName")
var fileName = test.gif
val file = File(folderPath + File.separator + fileName)
// Network call for downloading the image
Rx2AndroidNetworking
.download(url, folderPath, fileName)
.setPriority(Priority.IMMEDIATE)
.build().startDownload(object : DownloadListener {
override fun onDownloadComplete() {
if (mGIFViewListener != null) {
progress_bar.visibility= View.GONE
// File that you share at last val uri = FileProvider.getUriForFile(mContext, BobbleConstants.PROVIDER_AUTHORITY, file)
mGIFViewListener!!.onGIFShare(uri)
}


}

override fun onError(anError: ANError) {
progress_bar.visibility= View.GONE
Log.d(TAG,"Networking error "+anError.message);
}
})

}

Now let’s see how do we improve our code and instead of making two network calls, get this done with a single network call and save time and processing.

As we all understand that glide keeps a cache of the image which we downloaded while showing in the list, why can’t we use the same image, or can we?

Well we tried using the cache images, but the issue with the caches is that they have .0 or some weird extensions which are not compatible with the URI and hence you will get File Format Not Supported Error.

So how do we do it?

Well, the adapter is still similar, it has now an extra method loadGif, which gets the url of the image and returns us a sharable image format.

// Loading the image in the recycler viewif (gif.url != null) {
gifUrl=gif.url
Glide.with(mContext)
.asGif()
.load(gif.url)
.fitCenter()
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(gifHolder.gifImage)
loadGif(gifUrl,gif)
}
// Using the cache image private fun loadGif(url:String,gif:Gif){
Single.fromFuture(Glide.with(mContext).asGif().load(url).submit())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<GifDrawable> {
override fun onSubscribe(d: Disposable) {}
override fun onSuccess(gifDrawable: GifDrawable) {
if (mGifPagerInterface != null) {
mGifPagerInterface!!.clickOnGif(gifDrawable)
}
}
override fun onError(e: Throwable) {
Log.d(TAG,"loadGIF errror"+e.message) }
})
}

Glide internally handles this, if we load an image from an url, then it makes a cache of it, and passing the same url again and calling the submit() function, you would get a Future, now you can easily share this file.

The process for storing the image in a file and then sharing the file still remains the same.

And here it is how it would look.

See, how fast that was on the same network 😍 😍 😍

Thanks, for giving it a read, hope it helps you in the future.

If you like the article make sure to leave some claps 👏🏿 👏🏿 👏🏿

Until next time, “may the code be with you”.

--

--