My problem is when i remove images from image View it remove image but when i monitor memory from android studio motorize tool it increasing memory
i am using Garbage collector .but its not good practice .
help me out with different solution.
private void cleanImages() {
img1.setImageDrawable(null);
}
public void clickClean4(View view) {
cleanImages();
System.runFinalization();
System.gc();
Runtime.getRuntime().gc();
}
You need to not only setImageDrawable(null); , but also recycle the bitmap.
You can do this by
if (!bitmapDrawable.getBitmap().isRecycled()) {
bitmapDrawable.getBitmap().recycle();
}
Hope it helps.
Related
I am trying to change the current user wallpaper.
I have set the set_wallpaper permission and it works.
But when I change the wallpaper I have to wait about 15 seconds to see the wallpaper change.
This is currious because if I check the lock screen it has already changed.
Here is my code:
public static void setWallpaper(final Context context, final Bitmap image){
Thread thread = new Thread() {
#Override
public void run() {
WallpaperManager wallpaperManager = WallpaperManager.getInstance(context.getApplicationContext());
try {
if(image != null){
wallpaperManager.setBitmap(image);
}
} catch (IOException ignored) {}
}
};
thread.start();
}
I'm on Android 6.
Any help would be appreciated.
Why you used a Thread for this purpose?
Remove that and use your code directly on MainThread and see your code works correctly and instantly changed user wallpaper!
It might be worth having a deeper look at the WallpaperManagers setBitmap method and the inner callback (ln 1055, ln 1713) ref
I am not entirely sure how this whole code works nor do I think this really helps you solving the problem but it might give you a hint.
See this question for a similar problem
I have a couple of frame-by-frame animations (animation-list). Loading any one of them to an ImageView is not a problem. The problem occurs when I try to load a different animation in the same ImageView.
private void startAnimation(int anim) {
mImageView.setImageResource(anim);
((AnimationDrawable) mImageView.getDrawable()).start();
}
This was the code that I was using. After getting java.lang.OutOfMemoryError after calling the function more than one time, I added the following code to try and clear the AnimationDrawable and the ImageView.
private void startAnimation(int anim) {
if (mImageView.getDrawable() != null) { //trying to clear if it's not empty
if (((AnimationDrawable) mImageView.getDrawable()).isRunning()) {
((AnimationDrawable) mImageView.getDrawable()).stop();
((AnimationDrawable) mImageView.getDrawable()).selectDrawable(0);
}
mImageView.setImageResource(null);
}
//starting animation here
mImageView.setImageResource(anim);
((AnimationDrawable) mImageView.getDrawable()).start();
}
Well, this didn't work. I've tried the solutions posted here and here and they also didn't work. I still keep getting OutOfMemoryError.
This is how I call the startAnimation function.
startAnimation(R.drawable.anim1);//works fine
startAnimation(R.drawable.anim2);//OutOfMemoryError
...
So, how do I free the memory, and load the animation? Note that I want to do this over and over again.
I finally got it to work by adding mImageView.getDrawable().setVisible(false, true) before starting a new animation.
I'm trying to clear some views from memory.
Here's the situation.
I have an Activity that I'll call it A and another B.
Now I press a button in Activity A that calls Activity B that creates a lot of views dynamically
After this, I press back button to return to Activity A
Repeat theses 2 steps a lot of times.
The result is, in DDMS, the number of objects and memory Allocated stills growing ( the number of objects is increased by 88 and Allocated by 0,002MB )
That means the views dont be removed from memory !
How do can I clear the views COMPLETELY from memory ?
Thx !
Update-
Here you go some new information
Basically, on my "real world" I have only one Activity that is created a lot of times. This occurs because I it have to communicate to a webservice and all the responses are created in that new instance of this Activity.
I tried to resolve this issue with the code below
#Override
protected void onDestroy() {
super.onDestroy();
nullViewDrawablesRecursive(mRootView);
mRootView = null;
System.gc();
}
and that is my nullViewDrawablesRecursive
private void nullViewDrawablesRecursive(View view) {
if (view != null) {
try {
ViewGroup viewGroup = (ViewGroup) view;
int childCount = viewGroup.getChildCount();
for (int index = 0; index < childCount; index++) {
View child = viewGroup.getChildAt(index);
nullViewDrawablesRecursive(child);
}
} catch (Exception e) {
}
nullViewDrawable(view);
}
}
And that is my nullViewDrawable
private void nullViewDrawable(View view) {
try {
view.setBackgroundDrawable(null);
} catch (Exception e) {
}
try {
ImageView imageView = (ImageView) view;
imageView.setImageDrawable(null);
imageView.setBackgroundDrawable(null);
} catch (Exception e) {
}
}
Basically I'm trying to remove all the views and childs from their parent (mRootView) before destroying the activity. It works pretty well, if I don't do this, the objects and memory usage increase more and more.
The point is, it's not perfect, apparently some type of views doesn't be destroyed. And I think I'm "reinventing the wheel", it seems to damn hard for a simple thing !
Again, thanks a lot for trying to help me!
Typically, you don't need to worry about clearing views from memory. You would let the virtual machine and Android framework handle this when it is necessary. However, you do need to be concerned with memory leaks. If your Activities are sharing/holding onto references to views, and they cannot be garbage collected, then that is a problem. You can start by reading about that here: http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html
Its hard to provide some more specific advice without seeing you code though...
In onDestroy() set the views to null and call the garbage collector.
#Override
public void onDestroy() {
super.onDestroy();
myView = null;
System.gc();
}
This can help the garbage collector by calling System.gc() but it isn't guaranteed that the memory is cleared. However as long as you don't have a leak, there shouldn't be a problem.
I have prepared no.of drawable animations.when application launch first animation will be start.i have two buttons(next and previous) with same activity.when i click on next button i got exception like,
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
My code is,
For getting drawable animations from drawable,
private void getAnimationForLetters(int mAnim) {
// TODO Auto-generated method stub
String anim = "capital_anim_" + new Integer(mAnim).toString();
final int resID = getApplicationContext().getResources().getIdentifier(
anim, "drawable", "my-package-name");
mImgLetter.clearAnimation();
mImgLetter.setBackgroundResource(resID);
mImgLetter.post(new Runnable() {
public void run() {
loadingAnimation = (AnimationDrawable) mImgLetter
.getBackground();
loadingAnimation.start();
}
});
}
my next button code is,
case R.id.btnNext_:
unbindDrawables(findViewById(R.id.imgLetter));
mLetterNum=mLetterNum+1;
getAnimationForLetters(mLetterNum);
my undind drawable method code is,
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
finally i got exception java.lang.OutOfMemoryError: bitmap size exceeds VM budget
It is showing exception here mImgLetter.setBackgroundResource(resID);
Please help me.
I have added following code to clear,
loadingAnimation.stop();
for (int i = 0; i < loadingAnimation.getNumberOfFrames(); ++i){
Drawable frame = loadingAnimation.getFrame(i);
if (frame instanceof BitmapDrawable) {
((BitmapDrawable)frame).getBitmap().recycle();
}
frame.setCallback(null);
}
loadingAnimation.setCallback(null);
It is working fine for only next or previous.First time click on next animation move to second animation,second time if i click on previous button i got exception like,
Canvas: trying to use a recycled bitmap android.graphics.Bitmap
please help me.
exactly - the system knows when to collect garbage, so calling that doesn't help in the least.
You have to really really manage your apps memory. 290x330 may not seem like much, but if you're using full RGBA that's 4 bytes per pixel and your image turns into 380K. If you have several of these you're going to run out of memory. Most Android devices are not like PCs - they have rather limited memory. Some have only 16M or 24M to run everything, including the OS and any other apps the user might be running concurrently.
You might try wrapping your routine to load resources with try/catch
While( ! success ) {
try {
// load resources
} catch (OutOfMemoryError E) {
// do something to use less memory and try again
}
}
It may happen if you use high resolution images for mobiles with less resolution and memory. Make use Drawable-hdpi, Drawable-mdpi, Drawable-ldpi folders and place your images with suitable resolution.
FYI.. mostly you may also see this error in emulator when heapSize is too less. Try to increase heap size using AVD manager
This link might help you
Supporting multiple screen resolutions
Look at the below link the out of memory has been discussed in detail.
Android Out of memory issue
For me Thomas's solution has worked in past.
Hope it helps.
you can use this to free memory:
system.gc();
I have a code below, this code works perfectly fine when you are trying to load one or two images. However, the problem is, when you have a lot of images in one Activity, all images must load first before you can get in. My question is, what is the best way to handle this images? I want the images to load one by one and not simultaneously. I want it to load just like the ListView made by Fedor "http://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview" (Note: I'm not using a ListView, I just want my images to load like that). Please help me, I would really appreciate it a lot. Thanks in advance!
class ImageDownlaodThread extends Thread {
ImageDownloadMessageHandler imageDownloadMessageHandler;
String imageUrl;
#Override
public void run() {
Drawable drawable = LoadImageFromWebOperations(imageUrl);
Message message = imageDownloadMessageHandler.obtainMessage(1, drawable);
System.out.println("Message sent");
}
}
class ImageDownloadMessageHandler extends Handler {
View imageTextView;
}
#Override
public void handleMessage(Message message) {
progressBar.setVisibility(View.GONE);
imageTextView.setVisibility(View.VISIBLE);
}
}
Drawable LoadImageFromWebOperations(String url) {
Drawable d = null;
InputStream is = null;
try {
} catch (IOException e) {
e.printStackTrace();
}
return d;
}
Would this tutorial help [TUT] ImageView with Loading Spinner:
http://www.anddev.org/novice-tutorials-f8/imageview-with-loading-spinner-t49439.html
It basically show's a spinner until the image has loaded from the remote site :-)
You could strip the code to show a blank space / whatever you want till it loads.
If you don't want anything to happen till it all loads, you could have a count of how many images there are and then increment this each time an image has loaded.
IMO, AsyncTask is the easiest way to do this; in fact, it was basically built for this sort of task.
There's really too much to discuss in a StackOverflow answer. Just see Painless Threading to get started.