java - 在 android 上创建了两次 Activity

标签 java android

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

我将从 UI 开始,我有一个按钮,一旦你点击它,就会启动一个 Activity 以获得结果。

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 类是其他两个 Activity 的包装器,一个用于从相机捕获图像,另一个用于从图库中获取图像。它返回所选图像的 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:
                //...

        }
    }
}

这是当用户点击按钮时预期发生的情况:

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

有时(通常有 50% 的机会)它按预期工作,但有时会发生这种情况:

  • 相机 Activity 开始。
  • 用户拍照。
  • 相机 Activity 再次开始。
  • 用户可以拍另一张照片或返回。
  • 无论哪种情况,返回到 GUI 类的 URI 都不存在。

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

  • GetImageActivity - onCreate
  • GetImageActivity - 调用相机 Activity

相机打开,拍完照片后它会说:

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

相机第二次打开。用户拍了另一张照片,然后:

  • GetImageActivity - onActivityResult
  • GUIActivity - onActivityResult

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

最佳答案

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

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

Android 可以选择销毁正在等待调用 onActivityResultActivity;特别是当可用内存不足时。一些设备在销毁任务堆栈上的 Activity 方面表现得更积极。我可以在设置为称为“严格模式”的 Debug模式的三星设备上可靠地重现该问题。

您可以通过记录对 onCreateonDestroy 的调用来验证这是否是您的问题。

在 Activity 被销毁的情况下,当需要处理 Activity 结果时,Android 将重新创建 Activity ,将savedInstanceState 传递给onCreate。因此,补救措施是检查 GetImageActivity.onCreate 中的 savedInstanceState 的值。如果它不是 null,则不要调用 startActivity,因为您的 Activity 正在重新创建以调用 onActivityResult.

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

关于java - 在 android 上创建了两次 Activity ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9576238/

相关文章:

java - 对使用反射的方法进行单元测试

android - 可扩展列表让 ChildView 每个 child 运行两次

java - 创建具有图像选择功能的图片查看器

java - CPU 单核 : Need volatile or synchronized?

java - 从文档创建但未附加的元素 : need to remove it explicitly?

android - 什么时候在 ViewModel 中处理 RxJava2 Disposable?

Android - 在多个 View 上呈现相同的视频

android - Jetpack 撰写 : MutableState<Boolean> not working as intended

java - 输入字符串 "type"自定义 ListView 抛出数字格式异常

java - 使用带水印的追加输出模式时的结构化流异常