Fragment为什么不用构造函数传递参数?

Fragment的构造方法通常不建议直接传递参数。我们先来看一下Fragment源码:

public Fragment() {

}

在源码中会发现,Fragment的构造函数是空的,所以他和普通类的创建对象的方式不太一样。接着我们看源码:

public static Fragment instantiate(Context context, String fname) {
    return instantiate(context, fname, null);
}

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);
         }
        /*获取Bundle原先的值,这样一开始利用Bundle传递进来的值,就放入f. mArguments. 只需要在Fragment中利用getArguments().getString("key");就能将参数取出来继续用 */
        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); 
    }
    //...
}

以上代码中我们发现instantiate这个方法的作用是创建了fragment对象,Fragment是用反射的方式创建的,而且有mArguments来控制参数那么当然要用特定的方式来传递参数。所以我们可以用bundle对象来传递参数:

Bundle bundle = new Bundle();
bundle.putSerializable("entity", entity);
fragment.setArguments(bundle);

Fragment的构造方法通常不建议直接传递参数,原因主要涉及以下几个方面:

  1. 「生命周期问题」:Fragment的生命周期比Activity更加复杂。直接在Fragment的构造方法中传递参数,可能会导致在Fragment重新创建时(如屏幕旋转等配置变更时),无法正确地恢复这些参数。
  2. 「与Fragment的恢复机制不兼容」:当系统因资源不足而杀死当前Activity时,它会保存Fragment的状态以便之后恢复。如果在构造方法中传递参数,这些参数将不会被系统自动保存和恢复。
  3. 「推荐使用的方式」:为了安全地向Fragment传递参数,推荐使用Fragment.setArguments(Bundle args)方法。通过这个方法传递的参数会与Fragment的实例状态一起被系统自动保存和恢复。
  4. 「解耦和可测试性」:避免在构造方法中直接传递参数有助于保持Fragment的独立性,使其更容易进行单元测试和与其他组件的解耦。
  5. 「避免无参构造方法的限制」:在某些情况下,系统可能需要通过无参构造方法来实例化Fragment。如果在构造方法中添加了参数,就可能会违反这一限制。

虽然从技术上讲可以在Fragment的构造方法中传递参数,但这通常被认为是不良的实践。


原文始发于微信公众号(沐雨花飞蝶):Fragment为什么不用构造函数传递参数?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/256059.html

(0)
李, 若俞的头像李, 若俞

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!