1. 程式人生 > >android Fragment裡的newInstance和建構函式

android Fragment裡的newInstance和建構函式

最近用android studio建立fragment時,總是預設會建立一個靜態工廠函式

    public static AFragment newInstance() {
        Bundle args = new Bundle();
        AFragment fragment = new AFragment();
        fragment.setArguments(args);
        return fragment;
    }

註釋裡還會提示用這個方法例項化一個fragment類,拋開設計模式之外的優勢,推薦這個方法的原因是因為這個預設建立的方法裡包含了儲存引數這一步操作。

fragment.setArguments(args);

如果系統在重建Fragment時,只會呼叫預設建構函式,這樣引數就會丟失了,例如在橫豎屏切換時,Fragment會重建,這時,通過FragmentState進行初始化時,會傳入引數值。

   public Fragment instantiate(FragmentHostCallback host, Fragment parent) {
        if (mInstance != null) {
            return mInstance;
        }
        final Context context = host.getContext();
        if
(mArguments != null) { mArguments.setClassLoader(context.getClassLoader()); } mInstance = Fragment.instantiate(context, mClassName, mArguments);//恢復狀態 if (mSavedFragmentState != null) { mSavedFragmentState.setClassLoader(context.getClassLoader()); mInstance.mSavedFragmentState = mSavedFragmentState; }

在進入一步的初始化中會設定引數,如果沒有儲存的話這裡就會出現引數丟失了。

 public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) {
        try {
            Class<?> clazz = sClassMap.get(fname);
            if (clazz == null) {
                // Class not found in the cache, see if it's real, and try to add it
                clazz = context.getClassLoader().loadClass(fname);
                sClassMap.put(fname, clazz);
            }
            Fragment f = (Fragment)clazz.newInstance();
            if (args != null) {
                args.setClassLoader(f.getClass().getClassLoader());
                f.mArguments = args;//設定構造引數
            }
            return f;
        } catch (ClassNotFoundException e) {
            throw new InstantiationException("Unable to instantiate fragment " + fname
                    + ": make sure class name exists, is public, and has an"
                    + " empty constructor that is public", e);
        } catch (java.lang.InstantiationException e) {
            throw new InstantiationException("Unable to instantiate fragment " + fname
                    + ": make sure class name exists, is public, and has an"
                    + " empty constructor that is public", e);
        } catch (IllegalAccessException e) {
            throw new InstantiationException("Unable to instantiate fragment " + fname
                    + ": make sure class name exists, is public, and has an"
                    + " empty constructor that is public", e);
        }
    }