美文网首页
【Android组件核心面试题】Fragment的构造函数为啥不

【Android组件核心面试题】Fragment的构造函数为啥不

作者: 小城哇哇 | 来源:发表于2023-10-18 22:04 被阅读0次

    Fragment的构造函数为啥不让传参?(B站)

    这道题想考察什么?
    1. 是否了解Fragment传参的真实场景使用,是否熟悉Fragment使用场景?
    考察的知识点
    1. Fragment参数处理在项目中使用与基本知识
    考生应该如何回答
    1.你在工作中,留意过在Android中Fragment构造函数传递参数的问题吗,你怎么看?

    答:

    在工作中,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对象

    再接着查看下instantiate:

                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);
                    if (!Fragment.class.isAssignableFrom(clazz)) {
                        throw new InstantiationException("Trying to instantiate a class " + fname
                                + " that is not a Fragment", new ClassCastException());
                    }
                    sClassMap.put(fname, clazz);
                }
                Fragment f = (Fragment)clazz.newInstance();
                if (args != null) {
                    args.setClassLoader(f.getClass().getClassLoader());
                    f.mArguments = args;
                }
                return f;
    

    以上代码中我们发现Fragment是用反射的方式创建的,而且有mArguments来控制参数那么当然要用特定的方式来传递参数了

    所以我们可以用bundle对象来传递参数:

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

    最后

    有需要面试题的朋友可以关注一下哇哇,以上都可以分享!!!

    相关文章

      网友评论

          本文标题:【Android组件核心面试题】Fragment的构造函数为啥不

          本文链接:https://www.haomeiwen.com/subject/viwcidtx.html