我忠实地遵循了这里的指导方针:http://developer.android.com/guide/topics/resources/runtime-changes.html。我很惊讶地发现使用RetainedFragment处理配置更改是多么容易。一切都在正常的事件流中正常运作。但是有一个小故障。如果我最小化应用程序并在很长一段时间后启动它,它会崩溃:
E/AndroidRuntime( 5734): FATAL EXCEPTION: main^M E/AndroidRuntime( 5734): Process: net.citibuzz.app.scool, PID: 5734^M
E/AndroidRuntime( 5734): java.lang.RuntimeException: Unable to start activity ComponentInfo{net.citibuzz.app.scool/net.citibuzz.app.scool.MapActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment net.citibuzz.app.scool.RetainedFragment: make sure class name exists, is public, and has an empty constructor that is public^M
E/AndroidRuntime( 5734): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)^M
E/AndroidRuntime( 5734): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2269)^M
E/AndroidRuntime( 5734): at android.app.ActivityThread.access$800(ActivityThread.java:139)^M
E/AndroidRuntime( 5734): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)^M
E/AndroidRuntime( 5734): at android.os.Handler.dispatchMessage(Handler.java:102)^M
E/AndroidRuntime( 5734): at android.os.Looper.loop(Looper.java:136)^M
E/AndroidRuntime( 5734): at android.app.ActivityThread.main(ActivityThread.java:5102)^M
E/AndroidRuntime( 5734): at java.lang.reflect.Method.invokeNative(Native Method)^M
E/AndroidRuntime( 5734): at java.lang.reflect.Method.invoke(Method.java:515)^M
E/AndroidRuntime( 5734): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)^M
E/AndroidRuntime( 5734): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)^M
E/AndroidRuntime( 5734): at dalvik.system.NativeStart.main(Native Method)^M
E/AndroidRuntime( 5734): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment net.citibuzz.app.scool.RetainedFragment: make sure class name exists, is public, and has an empty constructor that is public^M
E/AndroidRuntime( 5734): at android.support.v4.app.Fragment.instantiate(Fragment.java:413)^M
E/AndroidRuntime( 5734): at android.support.v4.app.FragmentState.instantiate(Fragment.java:97)^M
E/AndroidRuntime( 5734): at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1790)^M
E/AndroidRuntime( 5734): at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:213)^M
E/AndroidRuntime( 5734): at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:97)^M
E/AndroidRuntime( 5734): at net.citibuzz.app.scool.MapActivity.onCreate(MapActivity.java:134)^M
E/AndroidRuntime( 5734): at android.app.Activity.performCreate(Activity.java:5248)^M
E/AndroidRuntime( 5734): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)^M
E/AndroidRuntime( 5734): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2173)^M
E/AndroidRuntime( 5734): ... 11 more^M
E/AndroidRuntime( 5734): Caused by: java.lang.InstantiationException: can't instantiate class net.citibuzz.app.scool.RetainedFragment; no empty constructor^M
E/AndroidRuntime( 5734): at java.lang.Class.newInstanceImpl(Native Method)^M
E/AndroidRuntime( 5734): at java.lang.Class.newInstance(Class.java:1208)^M
E/AndroidRuntime( 5734): at android.support.v4.app.Fragment.instantiate(Fragment.java:402)^M
E/AndroidRuntime( 5734): ... 19 more^M
显然系统资源耗尽,杀死了活动实例,然后尝试在重启时重新创建它。这对我来说有点混乱。看起来系统正在以不同的方式处理两种情况:一种情况是由于配置改变而破坏活动,另一种情况是由于资源紧张而破坏它。我认为这一定是个常见问题。我该如何处理?
如果需要,我很乐意提供代码段,但正如我在开头所说的那样,我已将Google的示例代码添加到T中。
编辑: 好的,我意识到我确实做了一些改变。我添加了一个构造函数: - (
public class RetainedFragment extends Fragment {
// data object we want to retain
private MapState data;
private Context mContext;
public RetainedFragment(Context context) {
mContext = context;
}
// this method is only called once for this fragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment
setRetainInstance(true);
}
public void setData(MapState data) {
this.data = data;
}
public MapState getData() {
return data;
}
@Override
public void onDestroy() {
super.onDestroy();
}
...
}
答案 0 :(得分:1)
Caused by: java.lang.InstantiationException: can't instantiate class net.citibuzz.app.scool.RetainedFragment;
你不能在片段中有一个自定义构造函数,它需要调用它的空构造函数,如果它没有定义则会出现该异常
这是关于它的documentation:
Fragment的所有子类都必须包含一个公共空构造函数 框架通常会在需要时重新实例化一个片段类, 特别是在状态恢复期间,需要能够找到这个 构造函数来实例化它。如果没有空构造函数 可用时,在某些情况下会发生运行时异常 状态恢复。
顺便说一句,您可以通过调用getActivity();
调用活动的上下文来调用片段中对上下文的引用
如果要实例化片段,则需要创建一个静态方法,该方法将返回新创建片段的引用
public static RetainedFragment newInstance(int index) {
RetainedFragment f = new RetainedFragment();
// Supply index input as an argument.
Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);
return f;
}