1

I have a RecyclerViewAdapter which in onBindViewHolder, I make an AsyncTask call to download the image required from Google Cloud Storage.

There are some items in the RecyclerViewAdapter which call for the same image. I tried to deal with this by only downloading the image if it doesn't already exist in the local file storage; otherwise if it does then it uses the image that has already been downloaded.

Now what's happening is, if there are multiple items from the RecyclerView calling for the same image at near enough the same time, one of the items ImageView will just be blank/white but the rest of them will display the image correctly.

I was hoping to be able to capture this scenario and just use Thread.sleep and then try to get/use the file again but I'm not getting any exceptions thrown or anything so I'm not sure how to even capture that scenario to deal with it.

The only thing that I can see in the logcat which looks remotely helpful is the below:

D/skia: --- Failed to create image decoder with message 'unimplemented'

However it's not throwing an exception, it's just logging it as a message.

It does however point to there being an issue with the decoding of the image. So I checked the BitmapFactory.decodeFile documentation and it says that it returns a null if it couldn't decode it. So I tried to check if my bitmap was null after trying to decode but it never hit that IF statement meaning it was never returning null so I'm not sure what to do.

new Getlogos(holder.logoImageView.getTag().toString(), holder.itemView.getContext(), new Getlogos.AsyncResponse() {
    @Override
    public void returnBitmapURI(String URI, String tag) {
        if (holder.logoImageView != null && holder.logoImageView.getTag().toString().equals(tag)) {
            if (URI.contains("drawable://")) {
                int id = Integer.parseInt(URI.substring(11));
                Bitmap myBitmap = BitmapFactory.decodeResource(context.getResources(), id);
                holder.logoImageView.setImageBitmap(myBitmap);
            } else {
                Bitmap myBitmap = BitmapFactory.decodeFile(URI);
                holder.logoImageView.setImageBitmap(myBitmap);
            }
        }
    }
}).execute();

The issue only occurs sometimes and it doesn't happen to the same image consistently. it normally varies between some of the items that have the same image to download/use. Sometimes it doesn't occur at all.

Can anyone shed any light on where that skia message is coming from and how I can capture it when it fails to decode, so I can handle it?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Rafiq07
  • 37
  • 1
  • 11
  • by google storage you mean firebase storage? – ahuja007 Nov 21 '18 at 10:13
  • I mean [Google Cloud Storage](https://cloud.google.com/storage/) – Rafiq07 Nov 21 '18 at 10:15
  • Is there a reason you don't wanne use a library for this, for example Picasso Image Loader.. Picasso image loader will handle all this stuff for you and you can set the image source by a single oneliner. – Luciano Nov 21 '18 at 10:19
  • I try not to use libraries unless I have to. I suppose I think it might help me learn or understand more about how it all works. – Rafiq07 Nov 21 '18 at 10:28
  • when you set bitmap from uri it loads whole image with full width and full height so first crop the bitmap and set with respect to imageview instead of it use glide library – Chetan Shelake Nov 21 '18 at 10:48

2 Answers2

4

Use Glide to display image in recyclerView

Add this dependencies to build.gradle

implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'

Inside onBindViewHolder

Request option to show error image, placeholder image etc. CircularProgressDrawable for placeholder drawable(optional)

val circularProgressDrawable = CircularProgressDrawable(mContext)
        circularProgressDrawable.strokeWidth = 5f
        circularProgressDrawable.centerRadius = 30f
        circularProgressDrawable.start()

        val requestOption : RequestOptions = RequestOptions()
                .placeholder(circularProgressDrawable)
                .error(R.drawable.ic_error_1)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .priority(Priority.HIGH)
                .dontAnimate()
                .dontTransform()

initialize Glide as shown below

Glide.with(mContext)
            .load(model.imageUrl)
            .apply(requestOption)
            .into(holder.imageView!!)
Aniruddh Parihar
  • 3,072
  • 3
  • 21
  • 39
Chethan Kumar
  • 185
  • 1
  • 12
  • Even though this doesn't really answer my question, it is a usable workaround to the issue around implementing the required functionality myself, so I've marked it as an answer. Thanks for the example code on how to implement Glide. My RecyclerViewAdapter is a bit slower but it does look to be functioning correctly now after a bit of tweaking. – Rafiq07 Nov 21 '18 at 12:01
-1

If it occured like this:

Failed to create image decoder with message 'unimplemented'

You catch the exception by judging the "bitmap == null?" Like the following codes:
enter image description here

My English is not very well , I hope you can understand what I said!

DarkRob
  • 3,843
  • 1
  • 10
  • 27