Android研究Fragment
前言
Fragment,简称碎片,是Android 3.0(API 11)提出的,为了兼容低版本,support-v4库中也开发了一套Fragment API,最低兼容Android 1.6。
过去support-v4库是一个jar包,24.2.0版本开始,将support-v4库模块化为多个jar包,包含:support-fragment, support-ui, support-media-compat等,这么做是为了减少APK包大小,你需要用哪个模块就引入哪个模块。
如果想引入整个support-v4库,则compile ‘com.android.support:support-v4:24.2.1’,如果只想引入support-fragment库,则com.android.support:support-fragment:24.2.1。
因为support库是不断更新的,因此建议使用support库中的android.support.v4.app.
Fragment,而不要用系统自带的android.app.Fragment。而如果要使用support库的Fragment,Activity必须要继承FragmentActivity(AppCompatActivity是FragmentActivity的子类)。
问题归纳
Could not find Fragment constructor
本次排查Bug的fragment基于AndroidX1.1.0
线上bugly报了一个Could not find Fragment constructor,先看一下Fragment的构造函数
1 | /** |
主要看一下注释说明,如果你想要的使用非默认的构造函数,需要自己实现一个FragmentFactory去初始化,然后强烈推荐使用setArguments和getArguments存取参数。看了一下报错的类,可以基本确定是使用了带参数的构造函数
然后看一下报错的位置,在Fragment里搜索could not find Fragment constructor
1 | public static Fragment instantiate( Context context, String fname, |
可以看到这里通过反射,调用了空的构造函数
1 | Fragment f = clazz.getConstructor().newInstance(); |
但是对应的类没有空的构造函数,所以抛出了这个异常。然后看一下初始的地方,是FragmentActivity在onCreate中调用的mFragments.restoreSaveState(p);
解决方案:
Fragment必须有一个无参public的构造函数,否则在数据恢复的时候,会报crash
ps:手动测试发现私有的构造函数无法通过该Constructor.newInstance方法调用
to be continued…