尊重原创:http://blog.csdn.net/yuanzeyao/article/details/40922875
最近在项目中经常遇到旋转屏幕或者home键退至后台,然后恢复前台导致应用崩溃,崩溃log如标题所示,从log的信息来看,导致崩溃的原因是该Fragment没有提供一个默认构造函数(无参构造函数),经过深入分析发现,Activity中有Fragment,并且Fragment没有无参构造函数,那么这个崩溃非常容易出现,因为在旋转屏幕的过程中,Activity是会被销毁重建的,这个时候Actiivty上的Fragment必然也会被销毁,但是当Activity恢复的时候,Fragment也会被恢复,这个时候会调用到Fragment.instantiate函数,这个函数通过反射调用Fragment的默认构造函数,所以一旦我们的Fragment没有提供默认构造函数,就会导致应用崩溃。
其实在Google的官网是建议Fragment不要使用带惨淡构造函数的,应该使用一个静态的newInstance方法代替,将Fragment中需要初始化的值通过newInstance方法传递进去。
public class FirstFragment extends Fragment
{
private static final String TAG = "FirstFragment";
private int tmpValue;
private MyViewPager parent;
/**
* 静态工程方法
* @return
*/
public static FirstFragment newInstance(Serializable parent)
{
FirstFragment fragment=new FirstFragment();
Bundle bundle=new Bundle();
bundle.putSerializable("parent", parent);
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
Log.d("yzy", "FirstFragment-->onSaveInstanceState ");
outState.putSerializable("parent", this.parent);
outState.putSerializable("tmp",tmpValue);
}
@Override
public void onCreate(Bundle savedInstanceState)
{
Log.d("yzy","FirstFragment-->onCreate and saveDInstancesState is null->"+(savedInstanceState==null));
super.onCreate(savedInstanceState);
Bundle bundle=this.getArguments();
Log.d("yzy", "bundle-->"+bundle);
Log.d("yzy", "getArguments is null-->"+(bundle==null));
this.parent=(MyViewPager) bundle.getSerializable("parent");
if(savedInstanceState!=null)
{
Log.d("yzy", "parent is null and get from savedInstanceState");
this.tmpValue=(MyViewPager) savedInstanceState.getSerializable("tmp");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view=inflater.inflate(R.layout.fragment_first, container,false);
return view;
}
}
在newInstance函数中,通过setArgument方法将参数传入Fragment中,在Fragment的onCreate方法中取出这个参数,并赋值给成员变量,当Fragmetn恢复的时候,onCreate中我们依然可以从getArgument中获取值,并且对属性进行赋值,但是对于一些没有在构造函数中初始化的属性,如本例中的tmpValue,如果Fragment销毁了,我们可以在onSaveInstanceState中保存该值,然后到onCreate中还原。这样就可以避免Fragment在销毁的时候重要属性丢失...