android - Android 4.0 及更高版本中的 ImageView 内存不足错误位图

标签 android memory bitmap

我的代码出现错误:内存不足错误

下面是我的代码:

public class ViewFullImage extends Activity {

    //Bitmap bitmap;
    private Bitmap bitmap;
    private ImageView iv;
    private String ImgFile_Name;

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.view_draw_picture);

    Log.v("","===================== viewFullImage.java================");

    try{
    String  path = "mfc/cam_img/";


    int s_id=getIntent().getIntExtra("s_id", -1);
    int intentKey=getIntent().getIntExtra("iv", -1);

    iv = (ImageView)findViewById(R.id.iv_display);

    File Dir= Environment.getExternalStorageDirectory();
    File imageDirectory = new File(Dir,path);
    File file  = new File(imageDirectory, "img_"+s_id+"_"+intentKey+".jpg");

    ImgFile_Name = file.getAbsolutePath();

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = false;
    options.inSampleSize = 1;

    BitmapFactory.decodeFile(file.getAbsolutePath(),options);


    int h = options.outHeight;
    int w = options.outWidth;

    Log.v("","This is h : "+h);
    Log.v("","This is w : "+w);

    bitmap = BitmapFactory.decodeFile(ImgFile_Name,options);

    iv = (ImageView)findViewById(R.id.image);

    if(h<w)
    {

        iv.setImageBitmap(rotateBitmap(bitmap));
    }
    else{
        iv.setImageBitmap(bitmap);
    }
    }catch (Exception e) {
        // TODO: handle exception

        Log.v("","Exception : "+e);
    }
    }

    Bitmap rotateBitmap(Bitmap bitmap)
    {
        Matrix matrix = new Matrix();
        matrix.postRotate(90);
        Bitmap bitmap1 = Bitmap.createBitmap(bitmap, 0, 0, 
                bitmap.getWidth(), bitmap.getHeight(), 
                                      matrix, true);
        bitmap.recycle();
        bitmap=null;

        return bitmap1;
    }
}

在这门课中,我正在尝试显示来自 SD 卡的图像。我从其他 Activity 中调用此 Activity ,例如:

 Intent intent =new Intent(cxt,ViewFullImage.class);
 intent.putExtra("iv", 8);
 intent.putExtra("s_id", s_id);
 startActivity(intent);

请有人告诉我哪里做错了......

最佳答案

你没有做错任何事情,你不能在不知道它是否适合内存的情况下在 Android 中分配一个图像(甚至是一个大字符串)。

问题发生在 Android 4 设备中,因为那里有更多只有 16MB 堆的 4.0 设备。内存堆是您将在其中打开图像的内存。

要解决此问题,您应该根据需要缩放图像(取决于堆大小和图像大小)。以下是如何使用缩放解码的代码:

public static Bitmap decodeSampleImage(File f, int width, int height) {
    try {
        System.gc(); // First of all free some memory

        // 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 requiredWidth = width;
        final int requiredHeight = height;

        // Find the scale value (as a power of 2)

        int sampleScaleSize = 1;

        while (o.outWidth / sampleScaleSize / 2 >= requiredWidth && o.outHeight / sampleScaleSize / 2 >= requiredHeight)
            sampleScaleSize *= 2;

        // Decode with inSampleSize

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = sampleScaleSize;

        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (Exception e) {
        Log.d(TAG, e.getMessage()); // We don't want the application to just throw an exception
    }

    return null;
}

另一件事是,如果您不释放一些内存 (System.gc()) 并且您在许多图片之间单击/切换,您可能会用完内存。如果内存不足,您不想破坏应用程序,而是管理位图为空的情况。您也可以为此改进 Exception 的 catch 案例。

希望对您有所帮助。

关于android - Android 4.0 及更高版本中的 ImageView 内存不足错误位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17365155/

相关文章:

android - FileProvider 和二级外部存储

java - 我正在尝试使用 4 个点在 ImageView 上标记 4 个点。当我移动其中一个 View 时,另一个 View 会自动移动

iphone - 在线程中解除分配

php - 内存使用随着 Doctrine 批量插入变得疯狂

c - 将字符串存储在共享内存 C 上

android - 图片解码失败。提供的图像必须是位图

Java 扩展将位图(图像)作为字节数组返回为字符串,我需要在我的游戏中显示图像。如何?

java - 如何让按钮在一段时间内不可点击?

java - 进度对话框使异步任务中的 Activity 崩溃

java - 如何在android中合并2张图片?