最近看到MoboPlayer的Crash记录里面好多的
“Unable to instantiate fragment make sure class name exists, is public, and has an empty constructor that is public”,这种crash不是必现的crash。后来找到原因
所有的Fragment继承的BaseFragment里面有个非空的构造方法,还黑科技的传入的一些Context的示例,原来的代码:
public BaseFragment(int screenWidth, MainInterface mi,FragmentInfo lastInfo){
this.screenWidth=screenWidth;
this.mi=mi;
this.lastFragmentInfo=lastInfo;
}
public BaseFragment(){
super();
}
修改后
public BaseFragment(int screenWidth, MainInterface mi,FragmentInfo lastInfo){
Bundle arguments = new Bundle();
arguments.putInt(BUNDLE_WIDTH, screenWidth);
arguments.putSerializable(BUNDLE_LASTINFO,lastInfo);
}
public BaseFragment(int screenWidth, MainInterface mi) {
Bundle arguments = new Bundle();
arguments.putInt(BUNDLE_WIDTH, screenWidth);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mi = (MainInterface) getActivity();
Bundle arguments;
if ((arguments = this.getArguments()) != null) {
this.screenWidth = arguments.getInt(BUNDLE_WIDTH);
this.lastFragmentInfo = (FragmentInfo) arguments
.getSerializable(BUNDLE_LASTINFO);
}
}
原因在这:
Default constructor. Every fragment must have an empty constructor, so it can be instantiated when restoring its activity's state. It is strongly recommended that subclasses do not have other constructors with parameters, since these constructors will not be called when the fragment is re-instantiated; instead, arguments can be supplied by the caller with setArguments(Bundle)
and later retrieved by the Fragment with getArguments()
.
Applications should generally not implement a constructor. The first place application code an run where the fragment is ready to be used is in onAttach(Activity)
, the point where the fragment is actually associated with its activity. Some applications may also want to implement onInflate(Activity, AttributeSet, Bundle)
to retrieve attributes from a layout resource, though should take care here because this happens for the fragment is attached to its activity.