为什么片段的onCreate()有时在Activity的onCreate()之前被调用?

时间:2015-05-18 08:05:58

标签: android android-fragments android-lifecycle

最近我遇到了很难重现的问题。 当片段尝试使用Activity中的数据初始化ArrayAdapter时,会发生NPE。在Activity' onCreate方法中初始化的默认列表:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    mAccounts = new ArrayList<>();
    // ...
}

@Override
public List<Account> getAccounts(){
    return mAccounts;
}

该片段还在其 onCreate()中创建了一个列表适配器:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
    setHasOptionsMenu(true);

    //mAccountProvider is an interface implemented by the activity
    mAccounts = mAccountProvider.getAccounts();

    mAccountAdapter = new AccountAdapter(getActivity(), R.layout.account_list_item, mAccounts);
}

当调用默认的 getCount()方法时,NPE会出现在 AccountAdapter 中。原因是 mAccounts 为空。 这个问题很少出现,我无法重现它。

在活动的 onCreate()之前,何时可以调用片段 onCreate()? 根据源代码,Fragment的 onCreate()将在Activity的 onCreate()中调度。为什么在Activity的onCreate()完成执行后会调用它?

5 个答案:

答案 0 :(得分:6)

Fragments之后不调用Activities回调;片段是在活动期间调用的。

mAccounts

中致电super.onCreate()之前初始化Activity.onCreate()

答案 1 :(得分:5)

您的片段的

onCreate()可以在您的活动onCreate()方法完成之前调用。您的片段和onActivityCreated()中有onCreateView()个回调。您可以使用它 - 它在onCreate活动方法之后执行。

答案 2 :(得分:3)

这个错误可以通过启用&#34;不要保持活动来重现。在开发者选项中。我也遇到过类似的问题,并使用FunkTheMonk提供的解决方案解决了。

答案 3 :(得分:1)

最近遇到了这个问题。请参阅底部的堆栈跟踪。

正如FunkTheMonk所说,崩溃的原因是你的Activity中的自定义onCreate()代码(在super.onCreate()之后)在你的Fragment中定制的onCreate()代码之后执行(就在超级之后) .onCreate())

如果您确实需要在整个活动的onCreate()之后执行回调,请将您的代码片段放在onActivityCreated()而不是onCreate()

否则上述情况将在您的记忆力低且活动被回收时发生。

根据我的经验,当我的MyActivity发送一个意图时,一旦我通过按回键返回MyFragment,应用程序就会崩溃。

Caused by: java.lang.NullPointerException
   at MyFragment.onCreate(MyFragment.java:20)
   at android.support.v4.app.Fragment.performCreate(Fragment.java:1939)
   at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1029)
   at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
   at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1230)
   at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:2037)
   at android.support.v4.app.FragmentController.dispatchCreate(FragmentController.java:154)
   at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:289)
   at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:58)
   at MyActivity.onCreate(MyActivity.java:129)
   at android.app.Activity.performCreate(Activity.java:5248)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) 
   at android.app.ActivityThread.access$800(ActivityThread.java:139) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:136) 
   at android.app.ActivityThread.main(ActivityThread.java:5086) 
   at java.lang.reflect.Method.invokeNative(Native Method) 
   at java.lang.reflect.Method.invoke(Method.java:515) 
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
   at dalvik.system.NativeStart.main(Native Method) 

答案 4 :(得分:0)

我可能来不及回答但仍然。我几天前遇到过这个。当您使用动态片段时会发生这种情况,并且在布局中使用片段标记来显示片段。而是使用布局(最好是FrameLayout)。假设您使用的是支持片段库。

值得一试。