題記 :在開發中,我們無法避免與各種imageView打交道,無論是ViewPage、RecycleView加載圖片瀑布流等、頭像的加載等。我想大家在與形形色色的圖片打交道的過程中,一定遇到過這樣的一個問題,在瀏覽界面時候,隨便滑動了幾下,app就非正常退出了,這很可能就是由於加載了bitmap,導致oom(out of memory)了。
那如何避免這種情況呢?我們在app開發中,可以從兩個方向來處理這個問題,現在我們 先說說如何從資源端(圖片上傳部分)來儘可能的避免上述的問題;
*圖片按比例大小壓縮方法(根據路徑獲取圖片並壓縮)
/**
* 圖片按比例大小壓縮方法(根據路徑獲取圖片並壓縮)
*
* @param srcPath 圖片路徑
* @return
* @auther: AnJun
* @create: 2017/2/22
*/
private static Bitmap getImage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;
newOpts.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
newOpts.inJustDecodeBounds = false;
int width = newOpts.outWidth;
int height = newOpts.outHeight;
int reqHeight = 800;
int reqWidth = 480;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
newOpts.inSampleSize = inSampleSize;
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);
}
* io流壓縮方法,此處限定圖片最大值
/**
* io流壓縮方法,此處限定圖片最大值
* 這裏限制不大於1000k
*
* @param image 資源圖片
* @return
* @auther: AnJun
* @create: 2017/2/22
*/
private static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 100;
while (baos.toByteArray().length / 1024 > 1000) {
options -= 10;
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
return bitmap;
}
*隨後,我們把獲取到的bitmap存儲到本地文件路徑中
/**
* 將壓縮的bitmap保存到SDCard卡臨時文件夾,用於上傳
*
* @param filename 圖片路徑
* @param bit 圖片
* @return
* @auther: AnJun
* @create: 2017/2/22
*/
private static String saveMyBitmap(String filename, Bitmap bit) {
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/LX_img/";
String filePath = baseDir + filename;
File dir = new File(baseDir);
if (!dir.exists()) {
dir.mkdir();
}
File f = new File(filePath);
try {
f.createNewFile();
FileOutputStream fOut = null;
fOut = new FileOutputStream(f);
bit.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return filePath;
}
* 下面,我們加入了圖片旋轉角度判斷
/**
* @auther: AnJun
* @create: 2017/2/22
* 判斷照片角度
*/
public static int readPictureDegree(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
/**
* @auther: AnJun
* @create: 2017/2/22
* 旋轉照片
*/
public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {
if (bitmap != null) {
Matrix m = new Matrix();
m.postRotate(degress);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
return bitmap;
}
return bitmap;
}
/**
* 清除緩存文件
*/
public static void deleteCacheFile() {
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/LX_img/");
RecursionDeleteFile(file);
}
* 爲了能全部刪除,我們調用了遞歸刪除
/**
* @auther: AnJun
* @create: 2017/2/22
* 遞歸刪除
*/
private static void RecursionDeleteFile(File file) {
if (file.isFile()) {
file.delete();
return;
}
if (file.isDirectory()) {
File[] childFile = file.listFiles();
if (childFile == null || childFile.length == 0) {
file.delete();
return;
}
for (File f : childFile) {
RecursionDeleteFile(f);
}
file.delete();
}
}
下面我會附上項目中使用的bitmaputil工具類,希望能對大家有幫助。