android Fragment里的newInstance和构造函数

来源:互联网 发布:mac支持的大型网游 编辑:程序博客网 时间:2024/05/17 22:39

最近用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);        }    }
0 0
原创粉丝点击