在android上创建两次活动

时间:2012-03-06 00:31:21

标签: java android

首先,我是Android开发的新手,所以请耐心等待。

我将从用户界面开始,我有一个按钮,一旦你点击它,就会为结果启动一个活动。

public class GUIActivity extends Activity

    @Override
    public void onClick(....){
        Intent intent = new Intent(getApplicationContext(), GetImageActivity.class);
        intent.putExtra("action", FROM_CAMERA);
        startActivityForResult(intent, GET_IMAGE);
    }

    @Override
    onActivityResult(int requestCode, int resultCode, Intent data){
        Log(TAG, "onActivityResult");
        //handle result
    }

}

GetImageActivity类是另外两个活动的包装器,一个用于从相机捕获图像,另一个用于从图库中获取图像。它返回所选图像的Uri对象。

public class GetImageActivity extends Activity{
    private Uri mediaUri;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Bundle extras = getIntent().getExtras();
        int action =  extras.getInt("action");

        Log.d(TAG, "onCreate");

        switch(action){
            case FROM_CAMERA:
                mediaUri = Uri.fromFile(new File(....));
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mediaUri);

                Log.d(TAG, "Calling camera activity"
                startActivityForResult(intent, action);
                break;
            case FROM GALLERY:
                //...
        }            
    }

    @Override
    onActivityResult(int requestCode, int resultCode, Intent data){
        Log.d(TAG, "onActivityResult");

        switch(requestCode){
            case FROM_CAMERA:
                if(resultCode == Activity.RESULT_OK){
                    Intent data = new Intent();
                    data.putExtra("uri", mediaUri);
                    setResult(Activity.RESULT_OK, data);
                    finish();
                }else{
                    Log.e(TAG, "Camera activity failed!");
                    setResult(Activity.RESULT_CANCELED);
                    finish();
                }
                break;

            case FROM_GALLERY:
                //...

        }
    }
}

当用户点击按钮时,预计会发生这种情况:

  • 相机活动应该开始。
  • 一旦用户拍照,它应该将其URI发送回GUI类。

有时(它通常有50%的几率)它可以预期运行,但有时会发生这种情况:

  • 相机活动开始。
  • 用户拍照。
  • 相机活动重新开始。
  • 用户可以拍摄另一张照片或返回。
  • 无论哪种情况,都不存在返回GUI类的URI。

我添加了几个调试日志行来跟踪事件序列。当我得到不良行为时,这就是我得到的输出:

  • GetImageActivity - onCreate
  • GetImageActivity - 调用相机活动

相机打开,一旦我拍了照片就说:

  • GetImageActivity - onCreate(再次)
  • GetImageActivity - 调用相机活动
  • GetImageActivity - onActivityResult

相机第二次打开。用户拍摄另一张照片:

  • GetImageActivity - onActivityResult
  • GUIActivity - onActivityResult

所以我的问题是......什么可能导致GetImageActivity被调用两次?

4 个答案:

答案 0 :(得分:6)

问题是Activity生命周期的处理不当。

onCreate的第二次调用是为了处理结果。

Android可能会选择销毁等待Activity呼叫的onActivityResult;特别是当空闲内存不足时。有些设备在破坏任务堆栈上的活动方面似乎更具侵略性。我可以在设置为“严格模式”的调试模式的三星设备上可靠地重新创建问题。

您可以通过将来电记录到onCreate&来验证这是否是您的问题。 onDestroy

如果活动被破坏,则需要处理活动结果时,Android会重新创建Activity,并将savedInstanceState传递给onCreate。因此,补救措施是检查savedInstanceStateGetImageActivity.onCreate的值。如果不是null,则不要拨打startActivity,因为正在重新创建Activity以致电onActivityResult

或者,如果您需要保留任何状态,请覆盖onSaveInstanceState(Bundle outState)并将所需数据放入outState

答案 1 :(得分:3)

将其添加到AndroidManifest.xml中的Activity定义:

android:launchMode = "singleTask"

答案 2 :(得分:1)

将其添加到AndroidManifest.xml中的Activity定义:

android:launchMode = "singleInstance"

答案 3 :(得分:0)

当您致电startActivityForResult时,它告诉Android您希望将结果传递给正在进行该呼叫的Activity。这解释了您在记录GetImageActivity - onCreate (again)时看到的内容。

由于您在第一个活动中呼叫startActivityForResult,即GUIActivity,而不应在setResult中呼叫GetImageActivity以正确传递回到结果。

因此,在GetImageActivity.onActivityResult()致电finish()之前,您应致电setResult,以便当您返回GUIActivity时,它可以处理预期的结果。