Reusing the bitmap variable after recycle - android

I have recycled the bitmap variable and when I again tried to use the same variable I have some strange errors with reference to recycle. Any solution to this issue ?
java code:
image1.recycle();
image1=null;
LogCat:
05-29 11:35:42.139: E/AndroidRuntime(695): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap#2bbad018
05-29 11:35:42.139: E/AndroidRuntime(695): at android.graphics.Canvas.throwIfRecycled(Canvas.java:1038)
05-29 11:35:42.139: E/AndroidRuntime(695): at android.graphics.Canvas.drawBitmap(Canvas.java:1078)

Returns an immutable bitmap from the specified subset of the source bitmap. The new bitmap may be the same object as source, or a copy may have been made.
It seems that the createBitmap functions have the potential to re-use the bitmap that you provided. If that is the case, then you shouldn't recycle the temporary bitmap since your final bitmap is using it. One thing you can do is
if(tempBitmap != finalBitmap) {
tempBitmap.recycle();
}
That should only recycle the tempBitmap when it isn't the same as the finalBitmap. At least that seems to be what the documentation is implying.

Once you recycle the bitmap its memory is freed. That's mean that bitmaps data are gone from the memory. If you want to use again the same variable you have to decode the Bitmap againg .
if (image1 == null || image1.isRecycled()) {
image1 = BitmapFactory.decodeStream()
}

You can have check before recycling the bitmap, as like :
if (img != null && !img.isRecycled())
{
img.recycle();
img = null;
System.gc();
}
Here img is bitmap.
Try this type error is sloved.

Related

Android bitmap recycle: need to set null?

Is it necessary to set a Bitmap to null after recycling it, so that its memory can be freed?
In the following code:
private static Bitmap bmpConcatHV() {
Bitmap bmp = BitmapFactory.decodeResource(resId);
Bitmap bmp2 = concatVertically(bmp, bmp);
bmp.recycle();
bmp = null;
Bitmap bmp3 = concatHorizontally(bmp2, bmp2);
bmp2.recycle();
bmp2 = null;
return bmp3;
}
There are Lint warnings:
The value null assigned to 'bmp' is never used
The value null assigned to 'bmp2' is never used
Both bmp and bmp2 are local variables, so no.
BitmapFactory.decodeResource(resId);
bitmap has two part of information when loaded into memory
1- information about bitmap ==> exists in java used memory
2- information about pixels of bitmap (byte of array) ==>exists in c++ used memory
Bitmap.recycle() is used to free the memory of C++.
Garbage Collection will collection the part of java and the memory
Garbage Collection work when need memory but i need to use this reference now so will use
bmp = null; here i handle the part of java and be safe to make it null

Proper way to release bitmap memory

I'm developing my first Android app. I have a method that creates two bitmaps and returns a third bitmap which is an overlay of the second bitmap on top of the first bitmap. So basically, I don't need the two bitmaps once the third bitmap is created.
I've read some posts and articles about releasing bitmap memory and I'm a bit confused on how to handle it.
Do I have to release the bitmaps myself? If yes, what is the proper way to do so?Are they released when the method is finished? Should I just let the garbage collector release it?
public static Bitmap bitmapResizeOverlay(Context context, Uri selectedImage, int maxWidth,
int maxHeight, #DrawableRes int overlayImageResource) {
Bitmap selectedBitmap = bitmapResize(context, selectedImage, maxWidth, maxHeight);
Bitmap overlayBitmap = BitmapFactory.decodeResource(context.getResources(), overlayImageResource);
return overlayBitmapToBottom (selectedBitmap, overlayBitmap);
}
selectedBitmap.recycle()
method is used always in when you want clear the memory occupied with bitmap.
The down side of not recycling the bit map could be OOM (out of Memory Exception)

android - recyclerview - get bitmap

How can I get the bitmap from a recyclerview?
recyclerview.setDrawingCacheEnabled(true);
Bitmap bitmap = recyclerview.getDrawingCache();
recyclerview.setDrawingCacheEnabled(false);
 
Bitmap newBmp = bitmap.copy(bitmap.getConfig(),true);
And I'm getting an exception
java.lang.IllegalStateException: Can't copy a recycled bitmap
Change your code like this:
recyclerview.setDrawingCacheEnabled(true);
Bitmap bitmap = recyclerview.getDrawingCache();
Bitmap newBmp = bitmap.copy(bitmap.getConfig(),true);
recyclerview.setDrawingCacheEnabled(false);
Basically what's happening here is that when you call setDrawingCacheEnabled(false), the underlying Bitmap object that has been created is recycled. If you copy the bitmap before you recycle it, it should work as expected.

Custom GridView causes out of memory error while loading lots of images

I have a custom layout for gridview. Each raw of gridview contains a progressbar, two imageviews and two text views. The image size are thumbnail sizes. While i have to load lots of bitmaps eg:- 500 images , which causes out of memory error. the images are first time loading from Internet and then which is stored in SD card and the next time when you loading the gridview which is loading from SD card. How to overcome this issue. I have found lots of answers to overcome out of memory if the gridview is inflated with single imageview. Please suggest me how to overcome this issue while using custom layout.Let me know if you know any example projects that handle this out of memory error in gridview while inflating custom layout in gridview.
It would be best to create a class that extends Application . This
application class will give you onlowmemory() callback whenever
application goes low memory. on there you can write
public void onLowmemory() {
Runtime.getRuntime().gc(); }
which will invoke system GC method. Upon executing garbage collector
android will garbage all unused objects.
There is another way to solve this problem. In animation you can call
Runtime.getRuntime().gc(); to invoke garbage collector. also in
activity onDestroy() method u can call Runtime.getRuntime().gc();
so your problem will be solved
I am facing the same issue.
The OutOfMemoryError is usually caused by
The first approach is to
BitmapFactory.decodeFile(srcImg);
Since images are transformed into bitmap before displaying, lots of big bitmap usually cause the error.
To overcome this, I added the following function
public static Bitmap decodeWithBounds(String srcImg, int bounds) {
if (bounds > 0){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(srcImg, options);
if (options.outHeight > bounds || options.outWidth > bounds){
options.inSampleSize = Math.max(options.outHeight/bounds, options.outWidth/bounds);
}
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(srcImg, options);
} else {
return BitmapFactory.decodeFile(srcImg);
}
}
I use this function to decode bitmap, with bounds = grid size.
This solved most problem.
For very low end device, add a try{} catch (OutOfMemoryError e){} ...
try this code set in image for gridview out of memory
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 8;//you set size qulity for image(2,3,,4,5,6,7,8 etc..)
Bitmap preview_bitmap=BitmapFactory.decodeStream(is,null,options);
set this bitmap in your imageview
Solve the out of memory exception issue with this code
Bitmap bitmap = BitmapFactory.decodeStream(is);
if (bitmap != null) {
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 100, 100, true);
imageView = new ImageView(mContext);
imageView.setImageBitmap(resizedBitmap);
}

android create object and memory

If I create an object and assign it to a variable:
Obj obj1 = null;
obj1 = myFunction(params);
(here myFunction creates a complex object)
And later I reassign the variable:
obj1 = myFunction(otherparams);
Does in that moment a memory leak occur, because I did not destroy the previous object?
Here is the real situation:
Bitmap bmp;
bmp = drawMyBitmap(3);
//... some code
bmp = drawMyBitmap(4);
Will a memory leak happen here?
Of cource, I know that I must call bmp.recycle, but I can't do it, because the real code is the following:
Bitmap bmp;
bmp = drawMyBitmap(3);
imageView.setImageBitmap(bmp);
//... some code
// if I try to do recycle here - I receive java.lang.IllegalArgumentException: Cannot draw recycled bitmaps
// But I need to recreate bitmap every some minutes
bmp = drawMyBitmap(4);
imageView.setImageBitmap(bmp);
So, how can I recycle the bitmap and avoid memory leaks?
As I understand, your problem is just you can't recycle your Bitmap cause it's used.
It's pretty naive, so maybe it's wrong, but do this:
imageView.setImageBitmap(bmp);
//... some code
Bitmap tmp = bmp;
bmp = drawMyBitmap(4);
imageView.setImageBitmap(bmp);
tmp.recycle(); // As it's not anymore referenced by the ImageView, you can recycle the Bitmap safely
I didn't test it. Give feedback.
In the first case, you will release the first object's reference so the garbage collector will destroy it, leaving the second one live on memory because of new reference.
In the second case, if you are setting bitmaps to ImageViews, you can not recycle them because the view will not have the bitmap to draw the image and it will throw to you a bitmap recycled exception, so you are not "leaking" to much memory keeping 2 bitmaps on memory.
Try to use bitmap options to create them to optimise your memory comsuption if you want.
Bitmap bmp;
bmp = drawMyBitmap(3);
imageView.setImageBitmap(bmp);
//... some code
// if I try to do recycle here - I receive java.lang.IllegalArgumentException: Cannot draw recycled bitmaps
// But I need to recreate bitmap every some minutes
Bitmap temp = bmp; //try this
bmp = drawMyBitmap(4);
imageView.setImageBitmap(bmp);
temp.recycle();

Categories

Resources