首页 > 代码库 > Unable to instantiate fragment com.viewpager.demo.FirstFragment: make sure class name exists, is pub

Unable to instantiate fragment com.viewpager.demo.FirstFragment: make sure class name exists, is pub

尊重原创: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=http://www.mamicode.com/(MyViewPager) savedInstanceState.getSerializable("tmp");>
        在newInstance函数中,通过setArgument方法将参数传入Fragment中,在Fragment的onCreate方法中取出这个参数,并赋值给成员变量,当Fragmetn恢复的时候,onCreate中我们依然可以从getArgument中获取值,并且对属性进行赋值,但是对于一些没有在构造函数中初始化的属性,如本例中的tmpValue,如果Fragment销毁了,我们可以在onSaveInstanceState中保存该值,然后到onCreate中还原。这样就可以避免Fragment在销毁的时候重要属性丢失...

Unable to instantiate fragment com.viewpager.demo.FirstFragment: make sure class name exists, is pub