I refered through many resources but can't get right answer,
I have made an custom adapter to view images in a listview. This images are retrieved from memory card. Everything runs fine but while i scroll through the listview i get an OutOfMemory Exception. I have posting the code using which i retrive images from sdcard.
public void getFromSdcard() {
File file = new File(
android.os.Environment.getExternalStorageDirectory(),
"Tiles/.NoMedia");
if (file.isDirectory()) {
listFile = file.listFiles();
for (int i = 0; i < listFile.length; i++) {
f.add(listFile[i].getAbsolutePath());
}
}
}
here f is arraylist of string and i am passing it to an custom adapter following is the code for my custom adapter.
public class NewImageAdapter extends ArrayAdapter<Image> {
private ArrayList<Image> objects;
String packageName;
Activity act;
public NewImageAdapter(Activity context, int image_layout,
ArrayList<Image> objects) {
super(context, image_layout, objects);
this.act = context;
this.objects = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_item, null);
}
Image i = objects.get(position);
if (i != null) {
ImageView iv = (ImageView) v.findViewById(R.id.imagemenu123);
// TextView tv = (TextView) v.findViewById(R.id.commandText);
if (iv != null) {
Bitmap myBitmap = BitmapFactory.decodeFile(i.getImagePath());
iv.setImageBitmap(myBitmap);
// iv.setImageBitmap(i.getImageBitmap());
// tv.setText("Tiles Images");
}
}
return v;
}
}
Any solution to my problem:
use this concept this will help you, After that set the imagebitmap on image view
public static Bitmap convertBitmap(String path) {
Bitmap bitmap=null;
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bfOptions.inTempStorage=new byte[32 * 1024];
File file=new File(path);
FileInputStream fs=null;
try {
fs = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if(fs!=null)
{
bitmap=BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
}
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fs!=null) {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}
If you want to make a small image from large image with height and width like 60 and 60 and scroll the listview fast then use this concept
public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth,
int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(path, options);
return bmp;
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
I hope it will help you much.
You cam take help from developer site Here
You are using
Bitmap myBitmap = BitmapFactory.decodeFile(i.getImagePath())
to load bitmap.. which can load large bitmaps into the memory, make sure that you load them in required size only.
Follow Loading Large Bitmaps Efficiently
It is also a good practice to load these bitmaps in AsyncTask
.
For that follow Processing Bitmaps Off the UI Thread
Out of memory means well you need to load images in the listview only when they're in view and release them when not in view - load them dynamically.
You can also try incorporating a ViewHolder class in that adapter.
This is happening because you are creating bitmaps. when app heap goes full it gives out of memory.
For decoding your bitmaps use this method-
Out of memory while creating bitmaps on device
It will surely help you out.
May be you can try this:
Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
iv.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));
Hope it Helps!!
Actually I think Best thing is to find reson for error. Main reson for this "Out of Memroy" is that when u scroll gcc is allocating memory even you scroll up from down it will allocate separate memory for listview in other words ur memeory is getting wasted or redundantl used. Even in bitmap u can reduce emeroy allocation size by scalesize option but it is jsut short term solution for permanent solution i find out create a view array for every listview by finding out the size i.e. number of images in d card and when you scroll compare poistion with size of view when poistion get equal to size of view-1 u have reached end net unique memeroy has been allocated ,no separete memroy will be allocated in listview if u again scroll up or down coz u have reached to end of view array ,no furthur need for allocating memeroy, hence problem solved