由Android框架构造的保留片段(没有空构造函数)

时间:2014-05-09 12:05:54

标签: android android-fragments

我有一个调用setRetainInstance(true)的片段,这样就不会在方向更改时重新创建它。它有一个公共空构造函数。我的印象是框架永远不会(重新)创建已经setRetainInstance(true)应用于它们的片段。但是,我收到的例外情况表明它正在被创建:

java.lang.RuntimeException: Unable to start activity ComponentInfo{<foo>/<foo>.Activity}: android.app.Fragment$InstantiationException: Unable to instantiate fragment <foo>.SomeFragment: make sure class name exists, is public, and has an empty constructor that is public
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2063)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2088)
       at android.app.ActivityThread.access$600(ActivityThread.java:134)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4744)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
       at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment <foo>.SomeFragment.d: make sure class name exists, is public, and has an empty constructor that is public
       at android.app.Fragment.instantiate(Fragment.java:588)
       at android.app.FragmentState.instantiate(Fragment.java:97)
       at android.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1732)
       at android.app.Activity.onCreate(Activity.java:883)
       at <foo>.Activity.onCreate(SourceFile:57)
       at android.app.Activity.performCreate(Activity.java:5008)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2027)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2088)
       at android.app.ActivityThread.access$600(ActivityThread.java:134)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4744)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
       at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.InstantiationException: cannot instantiate class <foo>.SomeFragment; no empty constructor
       at java.lang.Class.newInstanceImpl(Class.java)
       at java.lang.Class.newInstance(Class.java:1319)
       at android.app.Fragment.instantiate(Fragment.java:577)
       at android.app.FragmentState.instantiate(Fragment.java:97)
       at android.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1732)
       at android.app.Activity.onCreate(Activity.java:883)
       at <foo>.Activity.onCreate(SourceFile:57)
       at android.app.Activity.performCreate(Activity.java:5008)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2027)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2088)
       at android.app.ActivityThread.access$600(ActivityThread.java:134)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4744)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
       at dalvik.system.NativeStart.main(NativeStart.java)

我的问题有两个:

  1. Android框架在哪些情况下会创建这些片段?我预感到,当一个活动关闭,垃圾收集并随后打开时。
  2. 我是否可以通过使用bundle将参数传递给片段来修复错误(如上面的异常报告中所示)? (见an answer to "Do fragments really need an empty constructor?"

1 个答案:

答案 0 :(得分:0)

  

Android框架在哪些情况下会创建这些片段?我预感到,当一个活动关闭,垃圾收集并随后打开时。

关闭。如果Android终止您的进程(例如,用户按下HOME,并且时间过去),则会出现这种情况,然后用户尝试以引导用户返回此先前活动实例的方式返回到您的应用程序(例如,最近的任务列表)。

  

我是否可以通过使用bundle将参数传递给片段来修复错误(如上面的异常报告中所示)?

可能。 Bundle将成为已保存实例状态的一部分,因此即使在这种情况下,您也可以使用已保存的数据访问Bundle。我说“可能”只是因为你没有说明你传递给片段构造函数的内容,并且Bundle无法保留任意对象。某些对象(例如,Socket)无法以这种方式保存。