【问题标题】:Fragment and null getActivity after onAttachonAttach 后的 Fragment 和 null getActivity
【发布时间】:2014-03-12 15:19:57
【问题描述】:

我试图了解在什么情况下 getActivity() 可以在 onAttach 之后的片段中返回 null。我通常在我的片段内的 onCreate 或 onCreateView 中启动异步任务,但我收到错误报告,表明有时 getActivity() 在异步任务完成时为空。错误报告通过 crashlytics 传入,但无法重现。

异步任务是“阻塞的”——我显示了一个不可关闭的模态进度条。还可以通过调用 setRequestedOrientation 来防止旋转。

我正在使用 v4 支持 Fragment 和 FragmentActivity。片段设置为保留状态。

我错过了什么?是否有其他可能导致片段分离的配置更改?

我尝试暂时启用旋转和 dev 选项以在离开后销毁活动,但仍然无法重现...

这是我的一个片段中的一些相关代码,在这种情况下,它有时会在activity.dismissSpinner 处与 NPE 中断:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    checkIfLoggedIn();
}

public void checkIfLoggedIn() {
    LoginActivity activity = (LoginActivity)getActivity();
    activity.showSpinner("Connecting, please wait...");

    AsyncTask<String, Void, JsonResponse> asyncTask = new AsyncTask<String, Void, JsonResponse>() {
        protected JsonResponse doInBackground(String... notused) {
            return cmsServer().getCurrentUser(getActivity());
        }

        protected void onPostExecute(JsonResponse result) {               
            LoginActivity activity = (LoginActivity)getActivity();
            activity.dismissSpinner();
            //...more stuff here
        }
    };
    asyncTask.execute();
}

【问题讨论】:

  • 你能把你的代码贴在这里清楚地了解情况吗?

标签: android android-fragments android-support-library


【解决方案1】:

如果您的应用进入后台或暂停,您是否会停止/取消您的AsyncTask

考虑以下场景:您的 AsyncTask 已执行,当进度条提示时,用户决定在等待任务完成时执行其他操作。她通过按下主页按钮来做到这一点。唉,这可能会破坏片段和活动。正在运行的AsyncTask 对此一无所知,完成后,getActivity() 方法调用(或指向不存在的 Activity 的局部变量)也可能返回null,从而导致您的应用程序崩溃。

【讨论】:

  • 好吧,我不想取消它,因为我不想在用户回来时重做它......我现在最好的猜测就是这种情况。我认为另一种方法是在异步任务完成时采取额外的防御措施,并检查片段是否仍然附加。
  • 您可以很好地进行nullisAdded() 检查,但您的AsyncTask 只会浪费资源。我不完全确定我是否理解“当用户回来时我不想重做”——如果用户没有登录,无论如何你都必须重试登录,对吧?
  • 好点。登录只是这种模式的一个例子。在其他情况下,我正在检索一些(可能很大)内容。我在想我不想重做那个请求,但也许让用户回到相同的屏幕和相同的状态更有意义......
【解决方案2】:

Fragment生命周期如下

根据Fragment生命周期onCreate()onCreateView()Activity创建之前被调用。所以当我们在这些方法中调用getActivity() 时返回null。 所以不要在 onCreateView() 中启动异步任务,而是在 onStart()onResume() 中启动它,以便 getActivity() 返回确切的 Activity 引用。

更多详情click here

【讨论】:

  • 这是不正确的。 onCreate 和 onCreateView 在 onAttach 之后被调用,并且该活动存在于那时。它的 onCreate 方法可能还没有完成,但是它存在并且片段中的 mActivity 不为空。引用:onActivityCreated(Bundle) 告诉片段它的活动已经完成了自己的 Activity.onCreate()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
相关资源
最近更新 更多