Unable to instantiate fragment com.viewpager.demo.FirstFragment: make sure class name exists, is pub,instantiate
尊重原創: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; } @Overridepublic void onSaveInstanceState(Bundle outState) {// TODO Auto-generated method stubsuper.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在銷毀的時候重要屬性丟失...