0

I am working with an application and have about 10 Recycle view, when i move between fragments, app crash with out of memory.
I am using a lot of images in this app
I want to know how to apply bitmap recycle as it's the main reason of the exception

My recycle adapter is:

  public void onBindViewHolder(MboViewHolder holder, int position) {
    GameEvent gameEvent = ev.get(position);
    holder.bindPhoto(holder,cnt,gameEvent.getEventImage());}

BindPhoto mwthod is:

public void bindPhoto(MboViewHolder mbo,Context cnt, String photoUrl) {
         mbo.img.setTag(photoUrl);
        Bitmap imgz = Tools.getPhoto(photoUrl, 0);

    if (imgz != null) {
        mbo.img.setImageBitmap(imgz);
        Log.e("NoDwnLd","No");
    } else {
        Bitmap largeIcon = BitmapFactory.decodeResource(cnt.getResources(), R.drawable.ic_default);
        mbo.img.setImageBitmap(largeIcon);
        new DownloadBitmap(cnt,mbo.img,"2").execute(photoUrl);
    }

My DownloadBitmap asynctask is:

public class DownloadBitmap extends AsyncTask<String, Void, Bitmap> {

private  int flag=0;
private  ImageView img;
private  String type;
private HashMap<String, Bitmap> map= new HashMap<>();
private Context cnt;
private String url;

public DownloadBitmap(Context cnt, ImageView img, String type) {
    this.cnt = cnt;
    this.img=img;
    this.type=type;
}

public DownloadBitmap(Context cnt, ImageView img, String type, HashMap<String, Bitmap> map) {
    this.cnt = cnt;
    this.img=img;
    this.type=type;
    this.map=map;
}


public DownloadBitmap(Context context) {
    this.cnt=context;
    this.flag=2;
}


@Override
protected Bitmap doInBackground(String... params) {
    Bitmap bitmap=null;
    if (cnt!=null){
    boolean check = new CheckInternetConnection(cnt).haveNetworkConnection();
    if (check) {
        try {
            url=params[0];
            if (url==null || url.equals("")) return null;
        InputStream in = new java.net.URL(url).openStream();
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = Globals.inSampleSize;
            bitmap = BitmapFactory.decodeStream(in,null,options);
            return bitmap;
    } catch (Exception e) {
        Log.e("ImageDownload", "Download failed: " + e.getMessage());
    }
    }

    }
    return bitmap;
}

@Override
protected void onPostExecute(Bitmap bitmap) {
    if(bitmap != null){
        bitmap=Tools.resizeImage(bitmap,500,500);
    //view.setImageViewBitmap(R.id.nt_img, bitmap);
      if(type == "1")  Tools.sendNotification(cnt, bitmap);
      if(type == "2") {
          if(img.getTag()!= null && img.getTag() == url){
              // keep all images stored on memory for fast retrieval
            //  map.put(url, bitmap);
            //  Log.e("url", url);
              // save the image inside the image holder
              //img.setImageBitmap(map.get(url));
              Log.e("DwnLD",img.getTag()+"");
              img.setImageBitmap(bitmap);
              Tools.storePhoto(img.getTag().toString(), bitmap);
          }
     //   Log.e("ImageDownload", "bitmap in imageview");
      }
        if (type == null){
         //   map.put(url, bitmap);
           // if (img!=null && map.get(url)!=null)img.setImageBitmap(map.get(url));
            if (img!=null)img.setImageBitmap(bitmap);
        }

    if (cnt != null && flag ==2){
        Tools.storePhoto(CreateEvent1Fragment.searchResult.get(0).getEventImage(),bitmap);
    //    Log.e("ImageDownload", "bitmap in imageview");
    }
    }
}

My Tools.resizeImage is:

public static Bitmap resizeImage(Bitmap bitmap,int newWidth,int newHeight){
    Bitmap resized = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
  return  resized;
}

My Tools.storePhoto is:

public static void storePhoto(String url,Bitmap image){
File img = null;
File env = new File(Environment.getExternalStorageDirectory() + Globals.DIR);
if(!env.exists()) env.mkdir();
String filename = extractUrl(url);
    img=new File(Environment.getExternalStorageDirectory()+Globals.DIR+filename);
if (!img.exists()) {
   // Log.e("PHOTOS",img.getAbsolutePath());
    try {
        FileOutputStream fos = new FileOutputStream(img);
        image.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
     }
}

My Tools.getPhoto is:

    public static Bitmap getPhoto(String url,int type){
    Bitmap bmp=null;
    String filename = extractUrl(url);
    File ff = new File(Environment.getExternalStorageDirectory()+Globals.DIR+filename);
    if(!ff.exists()){
        return bmp;
    }else {
       if (type != 1){
           bmp = Tools.decodeFile(ff);
           return bmp;
       }else {
           bmp = BitmapFactory.decodeFile(ff.getAbsolutePath());
           return bmp;
       }
       }
}

My Tools.decodeFile is:

        public static  Bitmap decodeFile(File f) {
    try {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE=70;

        // Find the correct scale value. It should be the power of 2.
        int scale = 1;
        while(o.outWidth / scale / 2 >= REQUIRED_SIZE &&
                o.outHeight / scale / 2 >= REQUIRED_SIZE) {
            scale *= 2;
        }

        o.inSampleSize = scale;
        o.inJustDecodeBounds = false;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o);
    } catch (FileNotFoundException e) {}
    return null;
}

I want to apply bitmap recycle... How can I do that?

ahmed saber
  • 331
  • 1
  • 3
  • 14
  • try use my methods on this answer, instead of your resize method http://stackoverflow.com/questions/41236948/android-splash-screen-does-not-display/41237293#41237293 – Noorul Dec 20 '16 at 11:05
  • In your manifest file add this android:largeHeap="true" for better understading see this http://stackoverflow.com/questions/27396892/what-are-advantages-of-setting-largeheap-to-true – Vishal Senjaliya Dec 20 '16 at 11:56
  • i need a solution for the large memory not solution for the crash thanks @E – ahmed saber Dec 20 '16 at 13:14
  • @Ahamed can't get it please explain – ahmed saber Dec 20 '16 at 13:15
  • Have you applied those method in your application? – Noorul Dec 20 '16 at 13:18
  • yes, when i display the image – ahmed saber Dec 20 '16 at 13:29
  • public static Bitmap getPhoto(String url,int type){ Bitmap bmp=null; String filename = extractUrl(url); File ff = new File(Environment.getExternalStorageDirectory()+Globals.DIR+filename); if(!ff.exists()){ return bmp; }else { if (type != 1){ bmp = Tools.decodeFile(ff); return bmp; }else { bmp = BitmapFactory.decodeFile(ff.getAbsolutePath()); return bmp; } } } -------------- – ahmed saber Dec 20 '16 at 13:30
  • public static Bitmap decodeFile(File f) { try {BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(new FileInputStream(f), null, o); final int REQUIRED_SIZE=70; int scale = 1; while(o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE) {scale *= 2;} o.inSampleSize = scale; o.inJustDecodeBounds = false; return BitmapFactory.decodeStream(new FileInputStream(f), null, o); – ahmed saber Dec 20 '16 at 13:31

1 Answers1

0

try using Libs Glide

https://github.com/bumptech/glide

change

if (imgz != null) {
     mbo.img.setImageBitmap(imgz);
    Log.e("NoDwnLd","No");
} else {
    Bitmap largeIcon = BitmapFactory.decodeResource(cnt.getResources(), R.drawable.ic_default);
    mbo.img.setImageBitmap(largeIcon);
    new DownloadBitmap(cnt,mbo.img,"2").execute(photoUrl);
}

to

  if(!photoUrl.isEmpty()) {
      Glide.with(this).load(photoUrl).error(R.drawable.ic_default).into(mbo.img);
    Log.e("NoDwnLd","No");
} else {
   Glide.with(this).load(R.drawable.ic_default).error(R.drawable.ic_default).into(mbo.img);
    new DownloadBitmap(cnt,mbo.img,"2").execute(photoUrl);
}
Nguyễn Trung Hiếu
  • 1,770
  • 1
  • 8
  • 18