I'm using View Pager to show images which are downloaded from the network in my application. The number of images could be from 5 to 20. I'm using Volley library to do the network operations. The app wasn't taking much memory before but now after adding the view pager, the app takes a lot of memory and every time i open this activity, the memory used in heap increase (checked from the log messages). I also used Eclipse Memory analyzer to check where the leak was and it is definitely the bitmaps and the multiple instances of this activity. There is definitely a leak, as this activity isn't getting GC'ed, some references are keeping this from getting garbage collected. I've added my implementation of the view pager here.
public class ViewPagerAdapter extends PagerAdapter {
Context context;
public ViewPagerAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return photoReferences.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
final ImageView im;
final ProgressBar pb;
View itemView = inflater.inflate(R.layout.place_photos_item, container, false);
im = (ImageView) itemView.findViewById(R.id.placeImage);
attributes = (TextView) itemView.findViewById(R.id.placeAttributes);
pb = (ProgressBar) itemView.findViewById(R.id.progressBarPhoto);
imageLoader.get(url, new ImageListener() {
public void onErrorResponse(VolleyError arg0) {
im.setImageResource(R.drawable.onErrorImage);
}
public void onResponse(ImageContainer response, boolean arg1) {
if (response.getBitmap() != null) {
im.startAnimation(AnimationUtils.loadAnimation(context, android.R.anim.fade_in));
im.setImageBitmap(response.getBitmap());
pb.setVisibility(View.GONE);
}
}
});
((ViewPager) container).addView(itemView);
return itemView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((RelativeLayout) object);
}
}
Also, I'm using the Bitmap Cache of size 3 times the number of screenBytes(screenWidth * screenHeight * 4). I'm testing on Nexus 4 running 4.3 and I never run into a OOM exception cause the heap size is huge on this device but the app can take more than 100 mb of memory(it will crash on most devices) if I open the activity again and again, and before it used to take around 16-20 mbs of memory no matter what. Here's the cache code.
public class BitmapCache extends LruCache<Object, Object> implements ImageCache {
public BitmapCache(int maxSize) {
super(maxSize);
}
@Override
public Bitmap getBitmap(String url) {
return (Bitmap) get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
Could anyone please suggest me what should I do to catch the leak? Is there anything wrong in the View Pager or my Volley usage? I'm not happy with the transition of the Pager as well, lags a bit, is that related?
Update: Here's the screenshot of MAT, possible leak. This is on every activity that uses Volley library. I've been reading a lot but I couldn't solve the problem. Is volley causing leak or am I doing something terribly wrong?