当从最近任务中重新打开应用且权限设置已更改时,onCreate()被调用。

13

问题标题可能听起来复杂,但这是我的情况。

我在一个活动中有一个地图片段。简单。 打开存储权限以允许地图显示,一切正常。 按Home按钮将应用程序置于后台,然后关闭存储权限并从最近的任务中打开应用程序,应用程序崩溃。

问题是,主活动不是调用 onResume(),而是调用主活动的 onCreate() 和 Map 片段的 onCreateView()。因此,会引发异常。

似乎当更改权限时,应用程序进程被终止,从而重新创建活动。

    09-24 14:42:55.071: E/AndroidRuntime(12918):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
09-24 14:42:55.071: E/AndroidRuntime(12918): Caused by: 
java.lang.NullPointerException: Attempt to write to field 'int android.support.v4.app.Fragment.mNextAnim' on a null object reference
09-24 14:42:55.071: E/AndroidRuntime(12918):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:718)
09-24 14:42:55.071: E/AndroidRuntime(12918):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
09-24 14:42:55.071: E/AndroidRuntime(12918):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:548)

来自Activity中super.onStart()的方法


1
生命周期方法未被更改。发生的情况是活动被系统销毁。这就是为什么您的活动会被重新创建并调用onCreate的原因。 - eddiecubed
你是说Activity被权限更改摧毁了吗?因为当权限更改时,虽然onResume()通常会被调用,但在我的情况下,该Activity中的映射片段却调用了onCreate()。 - WenChao
2
当权限更改时,活动总是被销毁。 - greywolf82
@ greywolf82 是的。但问题是依赖于该权限的相关片段仍然存在,导致应用程序崩溃。 - WenChao
我发现整个讨论都很难以置信。你能否在Activity的所有生命周期方法中添加日志记录,以便我们可以清楚地了解权限更改时发生的情况?这将非常有用,真正理解它。 - David Wasser
@DavidWasser 你好,如果有时间我会创建一个示例应用程序。但是这个想法是当你将依赖于权限的MapFragment的Activity置于后台时。你在后台更改了权限设置,并从最近任务选项卡返回应用程序时,应用程序进程被杀死,但Activity仍然尝试重新创建MapFragment,从而引发上述异常。临时解决方案是在onCreate()中使用popBackStackImmediate()。这听起来清楚吗?干杯! - WenChao
3个回答

1

我曾经遇到过应用程序权限的动态更改类似的问题。经过一番探索,我明白了一些有用的信息,希望对您也有所帮助。

更改权限会导致系统终止您的应用程序。现在,如果您从概述屏幕打开您的应用程序,它将重新启动您的应用程序,这是您崩溃的主要原因,因为您可能正在对片段对象执行操作,而它现在为空。

这里需要注意的一个重要点是,在终止之前,片段状态保存在savedinstance对象中。

为了防止崩溃,您应该使用以下代码获取片段实例 -

mapFragment = (MapFragment)getSupportFragmentManager().findFragmentByTag("MAP FRAG");

这里的“MAP FRAG”是你必须给你的片段标签名称。
如果有任何疑问,请分享。

0
现在可行的解决方案是在 Activity 的 onCreate() 中调用 getSupportFragmentManager().popBackStackImmediate();,以防止尝试重新创建地图片段。

在这种情况下,popBackStack() 不起作用,因为它是异步的。


0

也许有点晚了,但可能会对未来的其他人有所帮助:)

你应该检查一下传递给 onCreate(Bundle savedInstanceState)savedInstanceState 是否为 null。如果是 null,那么才可以这样启动 Fragment

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_layout_file);

        if (savedInstanceState == null) {
            // do fragment transactions here
        }
    }

好的,但是在onCreate()被调用后,onDestroy()也会被调用,以便关闭应用程序。savedInstanceState会防止我的应用程序结束吗? - Orcun Sevsay
1
@MiloRambaldi savedInstanceState 只包含应用程序的上一个状态信息(以防止由于 RAM 不足或任何权限切换而被系统停止)。它无法阻止应用程序被终止。 - Sazid

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