Reinitialize recycled Bitmap Android - android

What I'm trying to do is to reuse a Bitmap after recycling it. For doing that, I know that I have to initialize de Bitmap again, I'm doing it this way after calling recycle():
mapBitmap = Bitmap.createBitmap(map, 0, 0, map.getWidth(), map.getHeight());
but when I try to use it, i get
06-12 20:41:01.628 615-1470/com.example.project W/System.err: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap#5f1fba3
By the way, I have another Bitmap which I have to recycle and use later on, but this one works perfectly, the only difference between them is that I'm initiallizating this one using decodeFile() as follows:
bm = BitmapFactory.decodeFile(url);

Your problem is that you are using a recycled Bitmap to initialize another one.
In this line:
mapBitmap = Bitmap.createBitmap(map, 0, 0, map.getWidth(), map.getHeight());
you are using the map object which is a recyled Bitmap, and you can't create a new Bitmap using a recycled one, be sure to initialize it properly before calling Bitmap.createBitmap(map, ...) or don't call map.recycle() somewhere in your code before you have finished using it.

Related

how to recyle the bitmap which runs multi-thread

the activity displays the bitmap which load from the internet ,when I slip the ImageView,another bitmap will occur.I set the bitmap to ImageView and after recycle it, sometimes,the error has occurs.
the code:
mImageView.setImageBitmap(loadedBitmap);
if(loadedBitmap!=null && !loadedBitmap.isRecycled()){
loadedBitmap.recycle();
loadedBitmap=null;
}
It runs multi-thread,I can not put the operation of Bitmpa recycle ahead of setImageBitmap.
how should I do?
Well basically you cannot recycle a bitmap that you're currently using in your ImageView.
If you want to swap the bitmap in your ImageView then I would do it like this:
I would keep a reference to the Bitmap (in for example mLoadedBitmap), and when you download another one you do something like this:
final Bitmap oldBitmap = mLoadedBitmap;
mLoadedBitmap = downloadedBitmap;
mImageView.setImageBitmap(mLoadedBitmap);
if(oldBitmap!=null && !oldBitmap.isRecycled()){
oldBitmap.recycle();
}
You can write a multi-threaded application but do all the UI updates from the main thread.

Avoiding java.lang.OutOfMemoryError

Hi all I am developing live wallpapers, and I am using lot of bitmaps. I have tested my new live wallpaper for aboute a week, and it was up and runing perfectly, but as soon as I have uploaded it to a market I keep getting this kind of exceptions : java.lang.OutOfMemoryError for both android.graphics.Bitmap.nativeCreate and android.graphics.BitmapFactory.nativeDecodeAsset. I use this kind of lifecycle of an bitmap:
I create a reference like:
Bitmap dark = null;
Bitmap cave = null;
at onCreateEngine I init them like :
cave = BitmapFactory.decodeResource(getResources(), R.drawable.cave);
dark = BitmapFactory.decodeResource(getResources(), R.drawable.dark);
here is where it trows the exception. for these images: . and after all I draw them to an canvas like this:
canvas.save();
canvas.drawBitmap(bg, new Matrix(), new Paint());
canvas.drawBitmap(dark, new Matrix(), new Paint());
canvas.restore();
What Should I do? It is better to load the dark image just one picture and draw it to the canvas width*height times? Or Are there any methods to do? I think recycle or calling onDestroy. But I do not know when to call them because the exceptions are thrown at onCreate.Are the images too big? And why it is working smoothly on my device, and on the other devices it is throwing exceptions? The bitmaps are 1484*1484 dimension big and the clouds are 250*172 dimensional big, should they be in 2^x * 2^x dimension?
Just try to use Memory Optimizer and see where are you creating Memory Leaks. You can use Eclipse Memory Analyzer(MAT) for this. Its a very common problem with using bitmaps. By using BitMaps you need to be extra careful for memory leaks.

How to Clear Bitmap Memory in Android?

I created a Bitmap and use it in Canvas to draw a circle and this method is called every time the Activity gets called and Activity get called multi-times so that time I am getting some error like 1536000-byte external allocation too large for this process
I know that error is Memory issue but how to Clear bitmap and also use at second time Activity call..
My Code is :
private void Draw_Hold_Circle() {
Bitmap bitmap_hold = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas_hold = new Canvas(bitmap_hold);
canvas_hold.drawArc(rect_open, 0, 360, false, mOutlinePaint);
}
This Method is called 4 times and the MainActivity can call multi-time so How to maintain Bitmap and its Memory?
Is there any special reason why you want to mantain the image in memory? If I'm not wrong you call your method "everytime your activity is called" so I'm guessing you mean everytime it's started with startActivity(). If this is the case then there is no point on maintaning all the images in memory at once since the user will be able to see the one on your foreground activity. I would suggest you to save your image to a file on your onStop() method and rebuild it, if necessary, on your onResume() method.

createBitmap() leads me into a java.lang.OutOfMemoryError

i try to rotate 3 imageViews (or better the Bitmaps behind them) every 10-100ms.
i do the rotation like this:
ImageView ivLoad;
Bitmap bMapLoad;
....
Matrix mat=new Matrix();
mat.reset();
mat.postScale(1.55f, 1.55f);
mat.postRotate((float)currentLoadDegree+(float)LoadDegree);
bMapLoad = Bitmap.createBitmap(bMapLoadgr, 0, 0, bMapLoadgr.getWidth(), bMapLoadgr.getHeight(), mat, true);
ivLoad.setImageBitmap(bMapLoad);
ivLoad.setScaleType(ScaleType.CENTER);
....
the first time i start the app everthing works fine.
second time also works
but the 3rd time i start the app it crashs with the following error:
03-27 10:01:09.234: E/AndroidRuntime(3603): java.lang.OutOfMemoryError
03-27 10:01:09.234: E/AndroidRuntime(3603): at android.graphics.Bitmap.nativeCreate(Native Method)
03-27 10:01:09.234: E/AndroidRuntime(3603): at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
03-27 10:01:09.234: E/AndroidRuntime(3603): at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
after trying around a long time i found out that when i call System.exit(0) in the onDestroy methode everthing works.
now i don't know if there would be a better way because on google a lot of peaople mean that System.exit(0) is unsafe.
so will i get problems with this?
Instead of rotating the Bitmap, you could rotate the canvas you are drawing on.
canvas.save();
canvas.translate(-canvasWidth/2, -canvasHeight/2);
canvas.rotate(degrees)
canvas.drawBitmap( ... )
canvas.translate(-canvasWidth/2, -canvasHeight/2);
canvas.restore();
Now you only get a new bitmap, when the image itself is updated, even though you can rotate it as frequent as you like. But if you get a new Bitmap, you still need to call Bitmap.recycle() on the old one.
You shouldn't recreate the bitmap on every step of the rotation, instead you should just try to draw it rotated. That's also possible with a Matrix (what you already use) and will avoid the excessive memory usage.
Android: How to rotate a bitmap on a center point
You get OutOfMemoryError because you load the Bitmap every time you rotate ImageView. You should consider reusing already loaded bitmap. Also call Bitmap.recycle() method when you do not need the bitmap any more.

Android 2.1 View's getDrawingCache() method always returns null

I'm working with Android 2.1 and have the following problem:
Using the method View.getDrawingCache() always returns null. getDrawingCache() should return a Bitmap, which is the presentation of View's content.
Example code:
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final View view = findViewById(R.id.ImageView01);
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
final Bitmap bmp = view.getDrawingCache();
System.out.println(bmp);
}
I've already tried different ways to configure the View object for generating the drawing cache (e.g. View.setWillNotDraw(boolean) and View.setWillNotCacheDrawing(boolean)), but nothing works.
What is the right way, or what I'm doing wrong?
PS: In real code I want to apply getDrawingCache() on a ViewGroup like RelativeLayout. Is the behaviour the same when using a ViewGroup?
Bitmap screenshot;
view.setDrawingCacheEnabled(true);
screenshot = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
You need Bitmap.createBitmap(view.getDrawingCache()); as the Bitmap from which the reference is received by getDrawingCache() gets recycled.
use
onLayout(x, y, width, height);
for ex:
onLayout(0, 0, 100, 100);
before calling getDrawingCache
Never do these things in onCreate!
You can do it in a View.onClickListener or other place.
I know this doesn't answer your question, but....
Just as an aside for other developers reading this, if what you are really trying to do is have access to a custom view's contents, derive your custom view from an ImageView. And then create a canvas and bitmap that you are going to control/draw into/read and use setImageBitmap() to set your bitmap into the view object. From there on in you can ignore the canvas passed to you in the onDraw(canvas) method and just draw into your local canvas/bitmap instead.
Why would you need this? There is an oversight in the Canvas class in my opinion. The Canvas class gives you no way to read the canvas contents nor to get at the bitmap behind it. So if you ever need to read from a bitmap, for example to acquire an image dump of the view contents, there's no way I know of to do it, other than the method described above.
This won't work for the RelativeView problem originally described here in this thread but this might be of interest to new Android developers.
As far as I read the last days in the documentation you should onlycall setDrawingCacheEnabled or buildDrawingChache() but not both.
had the same problem and finally this partly works for me:
view.layout(0, 0, 1000, 100);
Bitmap b = view.getDrawingCache();
try {
b.compress(CompressFormat.JPEG, 95,
new FileOutputStream( Environment.getExternalStorageDirectory() + "/folder/name.jpg"));
catch (FileNotFoundException e) {
Log.e(LOGTAG, "error:" + e.getMessage());
}
the only problem is, that I can't get the full dimensions of my view.
view.getwidth returns null ...
Check out if your view is not bigger than the screen size. I found this and switched the dimensions of my view so, now it works =)
Android get full View as Bitmap

Categories

Resources