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

Zzo*_*okk 11 android android-lifecycle android-fragments

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

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

@Override
public List<Account> getAccounts(){
    return mAccounts;
}
Run Code Online (Sandbox Code Playgroud)

该片段还在其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);
}
Run Code Online (Sandbox Code Playgroud)

调用默认的getCount()方法时,NPE发生在AccountAdapter内部.原因是mAccounts为空.问题很少出现,我无法重现它.

如果是有可能,片段的的onCreate()在活动的前所谓的onCreate() ?根据源代码,Fragment的onCreate()在Activity的onCreate()中调度.为什么在Activity的onCreate()完成执行后调用呢?

Fun*_*onk 6

碎片后不调用活动回调; 片段是在活动期间调用的.

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


kop*_*kao 6

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


Ten*_* Yu 6

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

正如 FunkTheMonk 所说,崩溃是由于 Activity 中自定义的 onCreate() 代码(紧接在 super.onCreate() 之后)在 Fragment 中自定义的 onCreate() 代码(紧接在 super.onCreate() 之后执行)造成的。 ))

如果您确实需要在整个 Activity 的 onCreate() 之后有希望执行回调,请将代码片段放入onViewCreated(因为onActivityCreated()已弃用)而不是onCreate()

否则,当你的内存不足并且 Activity 被回收时,就会发生上述情况。

根据我的经验,当我的 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) 
Run Code Online (Sandbox Code Playgroud)


Ily*_*iev 5

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

  • 发生此问题的情况很多。如果您查看 FragmentActivity 的 onCreate() 方法,您将看到该活动首先将自身附加到片段,然后执行 super.onCreate()。所以不能保证你的代码会在你的片段的 onCreate() 之前执行。 (2认同)
  • 通常,当由于活动重新创建而恢复片段时会发生这种情况.首次启动活动时,您手动创建片段(在super.onCreate()之后),但在重新创建活动时,会在super.onCreate()中的某些代码中重新创建片段. (2认同)