0

I'm creating my own SlideShow activity where I have a ImageView and I just fill it with the proper image each time the user clicks on next or previous.

These images are big though, and as soon as I navigate through a couple of them I get an OutofMemory probably due to a memory leak of my fault.

The thing is, each time a new image is called, I try to null the previous bitmap so it's garbagecollected, but to no avail.

Am I missing something here?

I am attaching the very simple code of my activity:

public class SlideShowActivity extends Activity {
 private static final String LOG_TAG = SlideShowActivity.class.getSimpleName();
 private Bitmap currentBitmap;
 private Bitmap mDefaultBitmap;
 private ImageView imageView;
 private ImageButton buttonPrev;
 private ImageButton buttonNext;
 private int currentImageIndex;
 private String imguri[] = { "ruta1/imagen1.jpg", "ruta1/imagen2.jpg", "ruta1/imagen3.jpg", "ruta1/imagen4.jpg", "ruta1/imagen5.jpg", "ruta1/imagen6.jpg" };
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.slideshow);
 mDefaultBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.noimage);
 imageView = (ImageView) findViewById(R.id.imageViewCurrentImage);
 buttonPrev = (ImageButton) findViewById(R.id.imgbuttonprev);
 buttonNext = (ImageButton) findViewById(R.id.imgbuttonnext);
 currentImageIndex = 0;
 setCurrentImage(currentImageIndex);
 buttonPrev.setOnClickListener(new OnClickListener() {
 @Override
 public void onClick(View v) {
 currentImageIndex--;
 if(currentImageIndex < 0)
 currentImageIndex = imguri.length-1;
 setCurrentImage(currentImageIndex);
 }
 });
 buttonNext.setOnClickListener(new OnClickListener() {
 @Override
 public void onClick(View v) {
 currentImageIndex++;
 if(currentImageIndex == imguri.length)
 currentImageIndex = 0;
 setCurrentImage(currentImageIndex);
 }
 });
 }
 private void setCurrentImage(int idx) {
 currentBitmap = null;
 imageView.setImageBitmap(null);
 try {
 currentBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(getAssets().open(imguri[idx])),800, 480, true);
 imageView.setImageBitmap(currentBitmap);
 } catch (IOException e) {
 Log.d(LOG_TAG, "No se pudo abrir el recurso" + imguri[0]);
 imageView.setImageBitmap(mDefaultBitmap);
 }
 }
}
asked Dec 28, 2012 at 16:41
2
  • your image size is larger than you show.. so first calculate the size of your image then store into creatbitmapscale then use it....go it??? Commented Dec 28, 2012 at 17:46
  • isn't this what I'm doing already? Commented Dec 28, 2012 at 17:57

3 Answers 3

1

It's better to call bitmap.recycle() if the bitmap is no longer needed, this can make the system recycle the native memory more actively.

so the setCurrentImage(int idx) can be changed to

private void setCurrentImage(int idx) {
 imageView.setImageBitmap(null);
 currentBitmap.recycle();
 currentBitmap = null;
 try {
 Bitmap tempBitmap = BitmapFactory.decodeStream(getAssets().open(imguri[idx]));
 currentBitmap = Bitmap.createScaledBitmap(tempBitmap, 800, 480, true);
 tempBitmap.recycle();
 imageView.setImageBitmap(currentBitmap);
 } catch (IOException e) {
 Log.d(LOG_TAG, "No se pudo abrir el recurso" + imguri[0]);
 imageView.setImageBitmap(mDefaultBitmap);
 }
}
answered Dec 28, 2012 at 16:57
Sign up to request clarification or add additional context in comments.

2 Comments

this didn't solve the problem, my activity keeps increasing memory usage as I switch bitmaps...
This should free the memory of Bitmap, if your application keeps increasing memory, maybe you could use MemoryAnalyzer to identify where is leaking. You could refer to link for more info
0

Use ListView for this purpose .

Use the link : http://www.vogella.com/articles/AndroidListView/article.html

answered Dec 28, 2012 at 16:51

Comments

0

Well, I don't know what kind of effects can take when you change a lot of times the bitmap of a ImageView this way. But I think you should use the ViewPager that comes with the support library. This way, your implementation will be faster, since it automatically load the next and previous view and remove it when it's no more necessary. And it will be even better for the user, since he/she can slide the image.

To make it even better, you can use this library, that extends the functionality of the ViewPager:

http://viewpagerindicator.com/

answered Dec 28, 2012 at 16:53

2 Comments

I tried this, and it indeed suits my needs better, but I'm still getting increasing amounts of memory usage, are you sure it should automatically remove the views when they're not needed anymore?
Use this implementation of the PagerAdapter: developer.android.com/reference/android/support/v13/app/… "This version of the pager is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment. This allows the pager to hold on to much less memory associated with each visited page as compared to FragmentPagerAdapter at the cost of potentially more overhead when switching between pages."

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.