Android片段工厂方法与构造函数重载

Android片段工厂方法与构造函数重载,第1张

概述首先,我已经知道FragmentManager经常破坏,然后使用默认构造函数重新创建片段.编码器必须在工厂方法中将重要的事物保存在一束参数中,然后在每次在onCreate(Bundle)中重新生成片段时将它们取出. public class MyFragment extends Fragment { private static final String MY_STRING_CONSTAN 首先,我已经知道FragmentManager经常破坏,然后使用默认构造函数重新创建片段.编码器必须在工厂方法中将重要的事物保存在一束参数中,然后在每次在onCreate(Bundle)中重新生成片段时将它们取出.
public class MyFragment extends Fragment {    private static final String MY_STRING_CONSTANT = "param";    private int mIntegerMember;    @OverrIDe    public voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mIntegerMember= getArguments().getInt(MY_STRING_CONSTANT);    }}

我的问题是,这是有区别的:

// InsIDe MyFragment.javapublic MyFragment() {    // No-argument constructor required by the FragmentManager.}public static MyFragment newInstance(int param) {    // Factory method    MyFragment fragment = new MyFragment();    Bundle args = new Bundle();    args.putInt(MY_STRING_CONSTANT,param);    fragment.setArguments(args);    return fragment;}// Somewhere elseFragmentTransaction transaction = getFragmentManager().beginTransaction();transaction.add(R.ID.frame_layout,MyFragment.newInstance(123)).commit();

和这个:

// InsIDe MyFragment.javapublic MyFragment() {    // No-argument constructor required by the FragmentManager.}public MyFragment(int param) {    // Parameterized constructor    Bundle args = new Bundle();    args.putInt(MY_STRING_CONSTANT,param);    setArguments(args);}// Somewhere elseFragmentTransaction transaction = getFragmentManager().beginTransaction();transaction.add(R.ID.frame_layout,new MyFragment(123)).commit();

我看不到什么可以阻止FragmentManager调用无参数的构造函数.并且在保存参数化构造函数(Bundle对象)中的数据将在onCreate()期间保留并恢复,就像使用工厂方法一样.

解决方法 AndroID从未直接调用非默认构造函数(也不是工厂方法) – 从技术上讲,使用它并不重要.您可以在添加Fragment之前随时调用setArguments(在任意方法中,即使在构造函数中),如果重新创建Fragment,则该bundle将被保存/还原.视图还具有由AndroID调用的特殊构造函数,但如果需要,您可以自由使用任意参数(它们不会被AndroID调用).

Fragment.setArguments代码:

/** * Supply the construction arguments for this fragment.  This can only * be called before the fragment has been attached to its activity; that * is,you should call it immediately after constructing the fragment.  The * arguments supplIEd here will be retained across fragment destroy and * creation. */public voID setArguments(Bundle args) {    if (mIndex >= 0) {        throw new IllegalStateException("Fragment already active");    }    mArguments = args;}

片段代码:

/**     * Create a new instance of a Fragment with the given class name.  This is     * the same as calling its empty constructor.     *     * @param context The calling context being used to instantiate the fragment.     * This is currently just used to get its ClassLoader.     * @param fname The class name of the fragment to instantiate.     * @param args Bundle of arguments to supply to the fragment,which it     * can retrIEve with {@link #getArguments()}.  May be null.     * @return Returns a new fragment instance.     * @throws InstantiationException If there is a failure in instantiating     * the given fragment class.  This is a runtime exception; it is not     * normally expected to happen.     */    public static Fragment instantiate(Context context,String fname,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,e);        } catch (illegalaccessexception e) {            throw new InstantiationException("Unable to instantiate fragment " + fname                    + ": make sure class name exists,e);        }    }

当AndroID要创建片段的实例时,将调用Fragment.instantiate.它通过Class.newInstance简单的调用,它是使用默认的零arg构造函数创建一个类的Java方法.看这个代码,似乎没有问题,创建额外的构造函数和在其中调用setArguments.

作为惯例,使用片段时通常使用工厂方法.大多数official sample Fragment code也采用工厂方法.以下是一些可能的原因:

>如果您正在编写一个自定义构造函数(带有参数),那么您也必须指定一个零对象构造函数.一个常见的错误是创建一个自定义构造函数,但是忘记定义一个零对象构造函数 – 当AndroID尝试在重新创建片段时尝试调用零对象构造函数,这将导致崩溃.>创建自定义构造函数时,您可能会尝试直接将构造函数参数分配给字段.这是任何其他java类写的几乎相当(因此你将如何自然地想写类).由于AndroID只会调用片段上的零对象构造函数,所以这些数据将无法用于任何重新创建的实例.如你所知,使用setArguments是解决这个问题的方法.即使您可以在构造函数中执行此 *** 作,使用工厂方法使得更加明显的是,此类不能以正常方式构造,从而减少了上述错误(或类似情况)的可能性.

总结

以上是内存溢出为你收集整理的Android片段工厂方法与构造函数重载全部内容,希望文章能够帮你解决Android片段工厂方法与构造函数重载所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1132713.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存