有效地解码位图,避免OOM异常

时间:2014-04-08 08:57:15

标签: android bitmap

我写了一个多媒体应用程序。在这里我创建了一个带有viewpager的图库和一个FragmentStatePagerAdapter。我使用了FragmentStatePagerAdapter,这样每次我在内存中只有两个图像,每次用户滚动寻呼机时,旧图像被破坏,新图像在位图中解码。

我已经阅读了很多关于如何使用inSampleSize选项以智能方式有效加载位图的教程,并且我已经以这种方式实现了它。在我的手机运行很好,但在一些手机中我得到out of memory exception所以这就是我在每个片段中解码我的ImageView

    @Override
public void onActivityCreated(Bundle savedInstanceState) {

    super.onActivityCreated(savedInstanceState);

    try {
        ImageArray=org.apache.commons.io.FileUtils.readFileToByteArray(new File(_imagePaths.get(mImageNum)));
        if(MyApplication.getDeviceWidth() !=0 || MyApplication.getDeviceHeight()!=0)
            bitmap=decodeSampledBitmapFromResource(ImageArray,MyApplication.getDeviceWidth(), MyApplication.getDeviceHeight());
        else{
            DisplayMetrics metrics = MyApplication.getAppContext().getResources().getDisplayMetrics();
            bitmap=decodeSampledBitmapFromResource(ImageArray,metrics.widthPixels, metrics.heightPixels);

        }

        mImageView.setImageBitmap(bitmap);


    } catch (IOException e) {
        Log.e("ImageDetailFragment",e.getLocalizedMessage());
    } 

}




    public static Bitmap decodeSampledBitmapFromResource(byte[] array,int reqWidth, int reqHeight) {


    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    Bitmap b =BitmapFactory.decodeByteArray(array, 0, array.length,options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    if(b!=null)
        b.recycle();
    Log.i("inSampleSize", String.valueOf(options.inSampleSize));

    return  BitmapFactory.decodeByteArray(array, 0, array.length,options);

}

    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) {

    // Calculate ratios of height and width to requested height and width
    final int heightRatio = Math.round((float) height / (float) reqHeight);
    final int widthRatio = Math.round((float) width / (float) reqWidth);

    // Choose the smallest ratio as inSampleSize value, this will guarantee
    // a final image with both dimensions larger than or equal to the
    // requested height and width.
    inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}

Log.i("inSample size", String.valueOf(inSampleSize));


    if(sampleLimit==-1)
        return 2;


    return inSampleSize;
}

正如你所看到的(我认为)我有效地加载每个位图,如果屏幕较小inSampleSize则转为2

我的问题是我如何计算inSampleSize不仅取决于屏幕大小,还取决于我的应用程序可用的内存,因为在我的手机中我得到64MB但是我遇到了38MB或更少的平板电脑< / p>

0 个答案:

没有答案