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

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

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... mAccounts = new ArrayList(); // ... } @Override public List 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为空。 问题很少出现,我无法重现它。

什么时候可以在activity的onCreate()之前调用片段的onCreate() ? 根据源代码,Fragment的onCreate()在Activity的onCreate()中调度。 为什么在Activity的onCreate()完成执行后调用呢?

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

Activity.onCreate()调用super.onCreate()之前初始化mAccounts

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

通过在开发人员选项中启用“不要保留活动”,可以重现此错误。 我也遇到过类似的问题,并使用FunkTheMonk提供的解决方案解决了。

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

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

如果您确实需要在整个Activity的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) 

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

值得一试。