Android:调用相机意图后Activity被销毁

49

我有两个活动,A1和A2。A1调用A2,从A2中,我按如下方式调用相机意图:

launchIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
launchIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoPath);   
startActivityForResult(launchIntent,CAMERA_REQUEST);

它打开相机,我可以拍照。问题出现在我点击保存按钮(S3中的勾按钮)后。我的onActivityResult函数没有被调用,取而代之的是A2的onDestroy方法被调用。我有几步要在onActivityResult函数中完成。
我的第二个Activity(A2)的清单如下:
android:configChanges="keyboardHidden|orientation|locale"
android:screenOrientation="portrait

在HTC One X中,我的onActivityResult函数被调用,但在我的S3中第二个Activity(A2)被销毁。
我该如何解决这个问题?

需要那个屏幕方向吗? - user439931
是的,我希望我的应用程序在竖屏模式下 :) - Sudarshan
@Surdarshan 你好!你找到任何可行的解决方案了吗? - Deepak Vajpayee
你可能需要检查 noHistory=trueIntent.FLAG_ACTIVITY_NO_HISTORY。详情请参见此处:https://dev59.com/F3vaa4cB1Zd3GeqPIt0s#62107555 - mochadwi
6个回答

84

我在这篇SO帖子中找到了解决方案。 问题在于当你点击相机的“保存”按钮时,活动调用会更改方向方法并且它将被销毁和重建。尝试设置:

android:configChanges="orientation|screenSize"

在Android清单文件中(不仅仅是像这篇其他SO帖子中建议的android:configChanges="orientation"; 它对API级别13或更高版本无效)。

这对我防止了活动被销毁。


5
android:configChanges="orientation|keyboardHidden|screenSize" 的意思是在 Activity 运行时配置更改时,不要销毁并重新创建 Activity 实例,而是在运行时处理这些更改。此属性有助于避免在更改配置时丢失应用程序状态或数据。该链接提供了一个关于 Galaxy S3 在横屏模式下拍照会破坏 Activity 的解决方案的帖子。 - NBApps
谢谢,你救了我一命,android:configChanges="orientation|keyboardHidden|screenSize" 已经完美运行。 - sandeepmaaram
1
我遇到了同样的问题,并发现在开发者选项中标记了“不保留活动”选项。为了帮助其他开发人员,我留下了这条评论。 - Khizar Hayat

45
启动相机需要大量内存。因此,在内存较低的设备上,Android系统会关闭后台运行的活动,因此会调用onCreate()。 由于这个原因,您提供的照片路径变为空,您将无法获取保存的图像。
解决方案是在系统销毁您的活动时保存照片路径,然后再次恢复它。
@Override
    public void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub

            outState.putString("photopath", photopath);


        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        if (savedInstanceState != null) {
            if (savedInstanceState.containsKey("photopath")) {
                photopath = savedInstanceState.getString("photopath");
            }
        }

        super.onRestoreInstanceState(savedInstanceState);
    }

如果您正在 Fragment 上执行此操作。

@Override
    public void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub

            outState.putString("photopath", photopath));


        super.onSaveInstanceState(outState);
    }

    @Override
    public void onViewStateRestored(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        if (savedInstanceState != null) {
            if (savedInstanceState.containsKey("photopath")) {
                photopath = savedInstanceState.getString("photopath");
            }
        }

        super.onViewStateRestored(savedInstanceState);
    }

3
这是正确的答案,解决了问题。感谢提供活动和碎片的解决方案。真是一个很好的答案。 - Smeet
非常非常有帮助!谢谢! - Lukas
这种方法要好得多。 - Jemshit Iskenderov
2
我遇到了同样的问题,但我的片段 onSaveInstanceState 方法从未被调用。只有我的活动 onDestory 方法被调用。有什么解决办法吗? - Sandra
1
你能否提供一些谷歌开发者文档链接来验证你的说法,即低内存设备会关闭后台活动。 - Sandeep R
一些用户遇到了这个问题,但我无法重现它。是否有可能强制或模拟这种情况? - fegoulart

27
请确保您没有打开“不保留活动”开发者选项,因为它会销毁您正在离开的活动。

5
我刚刚浪费了一整天的时间来找出我的应用程序出了什么问题。非常感谢! - Kaloyan Roussev
5
您的应用程序仍应在“不保留活动”模式下正常运行,而不会崩溃,是吗? - tagy22
是的,但这不是正常行为。如果您启动了一个activityForResult并且失去了Activity A,相机意图的结果无论如何都无法重建Activity A。 - Omaraf
1
Android 应该能够重新创建它,这就是 onCreate() 和 onSavedInstanceState() 的作用。 - Leo supports Monica Cellio

13

相机应用程序需要大量内存,为了释放内存,操作系统必须关闭后台应用程序,包括您的应用程序。这对所有Android应用程序都是正常的。当相机应用程序返回时,您的活动将被重新创建。要保留活动状态信息,请覆盖onSaveInstanceState()以存储您的数据,并在onCreate()中读取它们。


我也期望它会调用onCreate方法,但它没有调用A2的onCreate。 - Sudarshan
你能否在陈述中发布谷歌开发者文档,供参考? - Sandeep R

2

对我而言,当我在开发者模式中启用了一个名为“不保留活动”的选项后,这种情况就会发生。取消选择该选项后,从相册或相机应用程序中选择图片返回时,活动将不会重新创建。


2

当我调用相机意图时,我的 Activity 中会有许多任务正在运行。 我有 GPS 位置监听器和许多其他任务。

当从相机意图返回后,我需要在地图上添加标记以标识图片拍摄的位置。 因此,如果用户拍摄多张图片,则应为每张图片显示标记。

如果每次调用相机意图时都销毁我的 Activity,那么之前关于标记和它们位置的所有信息都将丢失。 而且,我还必须重新初始化地图。这对我的应用程序来说是一个大问题。

而且,只有在横屏模式下拍照时才会出现这种问题。如果我在竖屏模式下拍照,到目前为止一切都很好。

我将尝试使用 android:configChanges="orientation|screenSize",如此处所建议的。 希望它会有所帮助!


1
好的,添加了这个清单后,我可以说问题已经解决了!干杯!此外,如果这与内存有关,那么当我拍摄纵向图像时也应该会发生,正如我所说,它只在横向模式下发生,因此很有道理认为这是由于方向而不是内存引起的。 - Moti Bartov

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