在Android中使用位图出现问题

4
我有以下问题:
First activity

安卓相机已经打开,用户可以拍照。一旦拍照完成,第二个活动将会启动。
Second activity

在这个活动中,用户有可能查看照片。为此,我从第一个活动中获取图片,就像这样:

在本活动中,用户有可能查看照片。因此,我从第一个活动中接收到图片,如下所示:

Bundle extras = getIntent().getExtras();

我创建了以下位图:

BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 5;
        options.inDither = true; 
        byte[] imageData = extras.getByteArray("imageData");
        myImage = BitmapFactory.decodeByteArray(imageData, 0,
                imageData.length, options);

        Matrix mat = new Matrix();
        mat.postRotate(90);
        bitmapResult = Bitmap.createBitmap(myImage, 0, 0, myImage.getWidth(),
                myImage.getHeight(), mat, true);
        //...operations on the bitmapResult

将结果位图存储到sdcard中,在离开此活动之前,回收位图以避免内存问题:

bitmapResult.recycle();
bitmapResult=null;

在完成所有这些步骤之后,我们继续进行第三个活动。

Third activity

在这个活动中,用户可以以不同的大小查看图片。图片来自sdcard
最大的问题是当用户在活动three中按下返回按钮时,会进入活动two,但我的应用程序会崩溃,因为它尝试对已被回收的位图执行操作。
如果我不在第二个活动中回收位图,当我通过应用程序上下移动几次时,我会遇到OutOfMemory Exception
有任何想法吗?

你有没有考虑在第二个活动的onResume方法中从SD卡重新加载位图? - Andrej Cvoro
问题在于我保存在SD卡上的是最终版本,在对其进行所有操作后。如果我重新加载它,这意味着我需要再次对其进行两次操作! - adrian
那么最好的方法可能是在第二个活动中拥有原始图像的位图副本,只有当活动被销毁时(即从第二个活动返回到第一个活动时)才回收它,并在第三个活动运行时将其保留在内存中。这样,您就可以避免内存不足异常,并在恢复第二个活动时仍然拥有图像的副本。 - Andrej Cvoro
1个回答

0

当用户处于活动2时,不要直接进入活动3(画廊)。 首先完成活动2并将结果返回给活动1。然后开始活动3

您的第一个/主要活动:

public class TakeAPicture extends Activity {

    public static final int REQUEST_PICTURE_WAS_TAKEN = 100;
    public static final int REQUEST_SHOW_GALLERY = 101;
    public static final int RESULT_PICTURE_WAS_TAKEN_SHOW_GALLERY = 102;
    public static final int RESULT_BACK_FROM_GALLERY = 103;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.takeapicture);

        Button btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent(getApplicationContext(),
                        PictureTaken.class);
                startActivityForResult(i, REQUEST_PICTURE_WAS_TAKEN);
            }
        });
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
        case REQUEST_PICTURE_WAS_TAKEN:
            if (resultCode == RESULT_PICTURE_WAS_TAKEN_SHOW_GALLERY) {
                Intent i = new Intent(getApplicationContext(), Gallery.class);
                startActivityForResult(i, REQUEST_SHOW_GALLERY);
            }
            break;
        default:
            break;
        }
    }
}

在你的第二个活动中,你需要做类似这样的事情:

public class PictureTaken extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.picturetaken);

        Button btn = (Button) findViewById(R.id.button2);
        btn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                PictureTaken.this
                        .setResult(TakeAPicture.RESULT_PICTURE_WAS_TAKEN_SHOW_GALLERY);
                PictureTaken.this.finish();
            }
        });
    }
}

敬礼


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接