I have the follow code to get the screenshot
View screen = getWindow().getDecorView();
screen.setDrawingCacheEnabled(true);
screen.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
screen.buildDrawingCache();
Bitmap bitmap = screen.getDrawingCache();
The code is in onOptionsItemSelected in UI thread.
It runs fine when I test it manually. However, when I run the app with monkey, bitmap is nullI am not sure if it always null in monkey mode or just occasionally since monkey's randomness.
Any ideas that why monkey could behave differently? I do not want to blindly add a null pointer checker in later code.
Thanks
you should use buildDrawingCache(true) because buildDrawingCache() is same as buildDrawingCache(false).Make sure to copy bitmap to another one before using getDrawingCache() like below.
Bitmap bt=Bitmap.createBitmap(screen.getDrawingCache());
because its copy our bitmap before recycle() if you call setDrawingCacheEnabled(false).
Related
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.
I am using WallpaperManager.setBitmap to set the device's wallpaper.
I have the permissions set correctly. It works fine for 99% of the times however sometimes it simply sets the default instead of mine.
There is no exception (I have try-catch and I have logs. No exception. No crashes. Nothing).
The method is void so there is also nothing to check after calling it.
It is just being called and instead of setting the given bitmap - it sets the default.
http://developer.android.com/reference/android/app/WallpaperManager.html#setBitmap(android.graphics.Bitmap)
Here's the code:
WallpaperManager.getInstance(context).setBitmap(bitmap);
The bitmap is not recycled (I am checking for it before reaching this line of code).
Any ideas what can go wrong or what alternative to use?
Using a resource is not an option as the bitmap is dynamically generated in memory.
The generated bitmap size, in my device's case (Nexus 5) is always the same: 2160x1920, regardless the successful or failure results.
Also - it is a PNG.
I will meanwhile run some tests with setStream instead:
http://developer.android.com/reference/android/app/WallpaperManager.html#setStream(java.io.InputStream)
Hopefully it works better ...
Try this method instead, to directly reference the bitmap as a drawable resource:
WallpaperManager.getInstance(context).setResource(R.drawable.myImageId);
The method call assumes your bitmap is in a drawable resource folder (and not e.g. assets).
See API docs for more details.
I'm having a problem with the Bitmap.copy function. This code works okay,
Bitmap tempBM = Bitmap.createScaledBitmap(sourceBitmap, sourceBitmap.getWidth(), sourceBitmap.getHeight(), false);
//Ensure that the bitmap is mutable and not copied from the original in the case where no scaling is required
m_bwBitmap = tempBM.copy(tempBM.getConfig(), true);
if (tempBM!=sourceBitmap)
{
tempBM.recycle();
}
But this doesn't...
m_bwBitmap = sourceBitmap.copy(sourceBitmap.getConfig(), true);
sourceBitmap starts as immutable and I want m_bwBitmap to be mutable.
It doesn't crash as such but it does break the debugger as if something has gone wrong in the android function somewhere. The application then crashes later on. If I replace it with the top code, everything works fine.
However, I have now started getting crash reports from JellyBean, throwing a null pointer exception on the line with the tempBM.copy on it. So, I have to sort this out but currently the top code is the only source that will work at all. I'm testing it on an Android 4.0 device.
Any ideas?
Okay, I think I have answered this (well at least halfway anyway).
It is something to do with the Bitmap.Config. If I change the line to
m_bwBitmap = sourceBitmap.copy(Bitmap.Config.ARGB_8888, true);
then it works fine.
Note, the original source bitmap comes from a line like this...
Bitmap sourceBitmap = BitmapFactory.decodeFile(pictureFile);
pictureFile is a GIF.
However, I don't really know why decodeFile is producing something with a seemingly invalid Config. If I check the config of sourceBitmap, it returns null ?!?
I'm implementing list that contains preview of different image filters (grayscale, sepia, etc.)
I want to move image processing out of UI thread, but I'm not sure is it safe. For example, when I'm calling AndroidBitmap_lockPixels for Bitmap of ImageView what will happen if UI thread will try to redraw ImageVIew?
EXAMPLE
public void someMethod(){
ImageView mImageView = /*initialization*/
final Bitmap bmp = ((BitmapDrawable) mImageView.getDrawable()).getBitmap();
new Thread(new Runnable(){
#Override
public void run(){
applyFilter(bmp);
}
}).start();
}
public native void applyFilter(Bitmap bmp);
I haven't tried this case yet; however, you're trying to modify the current being-used Bitmap on ImageView. I think when AndroidBitmap_lockPixels is called, some abnormal will happen, like crash on ImageView while trying to invalidate or something similar to Access Violation.
You can make a copy of the image, process it then apply the new Bitmap to ImageView; it's totally safe.
In that case, there's a chance that the Bitmap is directly referencing something in that ImageView. Otherwise, the Bitmap becomes just another set of 1s and 0s. You might be able to make a copy of the Bitmap and update the ImageView with the new image once you are done. Be careful about images on devices before Honeycomb (3.0) because they handle bitmaps weird, and you have to manage them almost like you would in a C++ program.
It shouldn't, but there's sometimes hidden things in Android, so watch out.
Update: there might be a way to modify the image without copying, but I'm basing this more off general graphics and not Android-specific
I have the following problem that some of you must know on my android app :
3288-byte external allocation too large for this process.
Out of memory: Heap Size=5959KB, Allocated=3922KB, Bitmap Size=18614KB
VM won't let us allocate 3288 bytes
Facts :
I'm creating a bitmap of the screen (so quite huge) and I manipulate it (changing size etc ...) for doing a flipping page animation.
It crashes only on a desire HTC : on galaxy s2 and kindle fire, no problems.
I'm already desallocating the current Bitmap everytime I create a new one with the following code :
Bitmap old = this.bitmap;
this.bitmap = bitmap;
this.invalidate();
if(old != null)
old.recycle();
I also tryied to call this function :
public void recycle() {
if (this.bitmap!=null)
this.bitmap.recycle();
System.gc();
Runtime.getRuntime().gc();
}
Severals time in my code, and sometimes it gets slightly better (like it crashes a little later), but that's still not good.
I spent a lot of time on this problem, and I don't really get how to fix it. It's like on forum there is a lot of misinformation, so I'm kinda lost.
Thanks, ask for more precision.
Edit :
Here is a code called a lot :
//set the foreground image with the current day
Bitmap b = Bitmap.createBitmap(visibleLayout.getWidth(), visibleLayout.getHeight(),Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
visibleLayout.draw(c);
viewBitmapNext.setBitmap(b);
viewBitmapNext.setVisibility(View.VISIBLE);
Where viewBitmapNext is an overwritted element of the View class. The setBitmap function is described above.
About the resizement, I do this line of code :
viewBitmapPrevious.setLayoutParams(new RelativeLayout.LayoutParams((int) (iterator - ((totalWidth - iterator) - activity.getResources().getDimension(R.dimen.margin_right))/2), RelativeLayout.LayoutParams.WRAP_CONTENT));
Again, tell me if you you want to know more.
I found out what was the problem. It will not be interresting for anyone, because it's a dumb error closely related to my project, but I say it anyway.
I actually had 2 errors :
one loop creating elements infinitly.
Two big pictures I put as a background after a certain action performed on a cheap phone ( I'm still on it but it should be easy to solve). I'll edit this answer when it's done.
To everyone that helped me, you couldn't find out the problem's solution (wasn't related to the bitmap-screen I do), but still it was helpful on it's way.
Thanks.