Setting bitmap to image from byteArray in Xamarin.Android with minimum Load on UI thread

Nikhileshwar :

I have a scenario of loading bitmap to a ImageView from a byteArray. I use the following code to achieve this.

Inside a class that extends ImageView

this.Post(() =>
{
    using (customImage = BitmapFactory.DecodeByteArray(byteArray, 0, byteArray.Count(), options))
    {
        using (var renderBitemap = customImage.Copy(Bitmap.Config.Argb4444, true))
        {
            customImage?.Recycle();
            options.Dispose();
            options = null;
            if (m_pdfParent.undisposedPageImages.Contains(m_pageIndex))
            {
                this.SetImageBitmap(renderBitemap);
            }

        stream = null;
    }
});

As you can see the bitmap conversion also occurs in the UI thread (It is a heavy process, right?), this blocks the UI.

1) On using only the SetimageBitmap method in the UI thread => I get an object disposed exception.

2) On removing the this.Post and running everything in the background thread => I get change an exception that only the thread that created a view can alter the View.

Is there a way to improve this code snippet?(Setting bitmap from byteArray to an ImageView without blocking the UI thread)

FreakyAli :

Since I was not able to find the actual code that I use usually I will just be guiding you through the process which should be more than enough.

As you can see the bitmap conversion also occurs in the UI thread (It is a heavy process, right?), this blocks the UI.

This is true Bitmaps, in general, are really heavy and can cause OOM without any doubts and hence handling them should be your utmost priority!, To handle bitmaps you need to do the following things that will optimize them to the maximum and really fast as well without blocking your UI.

  • Use the async methods to actually convert the bytes to bitmap using the following method:

    var bmp = await BitmapFactory.DecodeByteArrayAsync(byteArray, 0, byteArray.Count(), options);
    

This will not do the decoding on the UI thread and not freeze your application, Also do not add this into your using state as that would dispose of it while it is still being referenced by your Image which will, in turn, throw an exception.

Also, the options do not need to be disposed of they are not heavy at all and can be GC'd when the time is right just leave it as you can actually even reuse this later if needed!

Also, the Bitmap's recycle method recycles your bitmap ergo making it useless and REMEMBER if a UI element is using this bitmap you will be getting an object was disposed exception and the StackTrace sometimes will not be clear what caused it i.e. confusion for no apparent reason. The best way to handle this is only clean your Bitmaps when you know they are useless now i.e. on page level when you go to another page not when you are still using it, Also your page reappearing needs to be handled i.e. image should be reassigned so that the above exception is not thrown again!

Also, make sure you optimize your image bitmap to the size of the View holder i.e. make sure that your image is only supposed to be in which you can do with the below method

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=24324&siteId=1