Fragment的构造函数为啥不让传参?(B站)
这道题想考察什么?
- 是否了解Fragment传参的真实场景使用,是否熟悉Fragment使用场景?
考察的知识点
- 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老皮
还能解锁 《Android十大板块文档》 ,让学习更贴近未来实战。已形成PDF版
内容如下:
1.Android车载应用开发系统学习指南(附项目实战)
2.Android Framework学习指南,助力成为系统级开发高手
3.2023最新Android中高级面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨平台首要之选
7.Kotlin从入门到实战,全方面提升架构基础
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 性能优化实战+360°全方面性能调优
10.Android零基础入门到精通,高手进阶之路