在android上创建两次活动

Jua*_*hin 9 java android

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

我将从UI开始,我有一个按钮,一旦你点击它,开始一个活动的结果.

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
    }

}
Run Code Online (Sandbox Code Playgroud)

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:
                //...

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

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

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

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

  • GetImageActivity - onActivityResult
  • GUIActivity - onActivityResult

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

pzu*_*ulw 7

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

第二个调用onCreate是处理结果.

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

您可以通过记录对onCreate&的调用来验证这是否是您的问题onDestroy.

在被破坏的活动的情况下,当需要处理活动结果时,Android将重新创建Activity,传递savedInstanceStateonCreate.所以,补救措施是检查savedInstanceState你的价值GetImageActivity.onCreate.如果不是,null则不要进行任何调用,startActivity因为Activity正在重新创建呼叫onActivityResult.

(可选)如果您需要保留任何状态,则覆盖onSaveInstanceState(Bundle outState)并将所需数据放入其中outState.


nza*_*ala 5

将此添加到AndroidManifest.xml中的“活动”定义中:

android:launchMode = "singleTask"
Run Code Online (Sandbox Code Playgroud)