How to deal with Out of Memory exception in android:
In android we encounter with out of memory exception many times. The reasons are we don't have expanding memory and completely dependent on device
the memory available on phone. So we don't have control over external factors and will need to optimize memory at our end.
Reasons of Out of memory Error ::
1.Biggest reason is memory leak i.e, Context leaking or can say Activity Leaking,a Service has the same problems as Activity in this regard.
2.You are doing process that demands continuous memory and at a point it goes beyond max memory limit of a process.
3.When you are dealing with large Bitmap and load all of them at run time.
There are some technique to optimizing the memory ::
1.Flag Techique : A solution is to set android:hardwareAccelerated=true and android:largeHeap=true
It is available after android 3.0 and so many android devices still run on gingerbread(2.3+) so it is not a reliable solution.
DVM garbage collection (Memory Leakage) : DVM Garbage collection works same as JVM garbage collection, Make sure that whenever you are done with
object and dont need it anymore, so reference as null.
3.Out of memory exception when we load image on imageview in our listview.Images come in all shapes and sizes.In many cases It might be larger than
required for a typical appication UI.
When Decode Image normally::
String sdImage = "/sdcard/imageTesting/" + imageTestName;
Bitmap bitmap = BitmapFactory.decodeFile(sdImage);
Most of the Time It give Out of memory Exception when image size is large. So we can use bitmap Option.
String sdImage = "/sdcard/imageTesting/" + imageTestName;
BitmapFactory.Options ourOptions=null;
options = new BitmapFactory.Options();
ourOptions.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeFile(sdImage, null, ourOptions);
But It is not the Best Solution . Some time it also give out of memory Exception. So come on the other way.
public static Bitmap convertBitmap(String path) {
Bitmap bitmap=null;
BitmapFactory.Options ourOptions=new BitmapFactory.Options();
ourOptions.inDither=false;
ourOptions.inPurgeable=true;
ourOptions.inInputShareable=true;
ourOptions.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, ourOptions);
}
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fs!=null) {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}
I also have some limitations like: After the decode we can not make the scale of this bitmap.
Now the Next way.
public static Bitmap decodeBitmapPath(String path, int width,
int height) {
final BitmapFactory.Options ourOption = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, ourOption);
ourOption.inSampleSize = calculateInSampleSize(ourOption, width,
height);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(path, ourOption);
return bmp;
}
public static int calculateInSampleSize(BitmapFactory.Options ourOption,
int imageWidth, int imageHeight) {
final int height = ourOption.outHeight;
final int width = ourOption.outWidth;
int inSampleSize = 1;
if (height > imageHeight || width > imageWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) imageHeight);
} else {
inSampleSize = Math.round((float) width / (float) imageWidth);
}
}
return inSampleSize;
}
1 Comment(s)