看了 Arouter 的源码,我有一个疑问
在 RouterProcessor.java 中,获取 Fragment 的 RouteMeta 信息代码部分:
} else if (types.isSubtype(tm, fragmentTm) || types.isSubtype(tm, fragmentTmV4)) {
logger.info(">>> Found fragment route: " + tm.toString() + " <<<");
routeMeta = new RouteMeta(route, element, RouteType.parse(FRAGMENT), null);
} else {
throw new RuntimeException("ARouter::Compiler >>> Found unsupported class type, type = [" + types.toString() + "].");
}
这段代码判断的是,Route 注解的类是否是 android.support.v4.app.Fragment
或 android.app.Fragment
的子类型,但我使用的是 androidx 下的 fragment,包名为 androidx.fragment.app.Fragment
,实际上来说,是不匹配这个 FRAGMENT 的条件的,但在实际运行中,却是可以找到这个 Fragment,有疑惑呀。
上面的 Activity 的判断,在 androidx 下是没有问题的,虽然我们使用的 AppCompatActivity 是在 androidx.appcompat.app 包下,但他的父类查下去,依然是 android.app.Activity
,所以,我比较怀疑的是 Fragment 的这个问题,谁能来解惑一下呀
2条答案
按热度按时间okxuctiv1#
@MRwangqi 这应该是 Androidx 的 Android Gradle 插件的原因:
Arouter 的 dex 在这个插件的作用下被修改了。
android.support.v4.app.Fragment
被替换成androidx.fragment.app.Fragment
。这导致
types.isSubtype(tm, fragmentTmV4)
实际上在 dex 中的逻辑是object instanceof androidx.fragment.app.Fragment
,而这个条件是可以通过的。android.enableJetifier:该标记设置为 true 时,Android 插件会通过重写其二进制文件来自动迁移现有的第三方库,以使用 AndroidX 依赖项。如果未指定,该标记默认为 false。
相关的参考链接如下:
AndroidX 概览
jetifier
wtlkbnrh2#
@hellowmq 感谢回复,我看了下 jetifier 的源码部分和试验了一下,在 JetifyTransform 中,会对 jar、aar 的 Class 进行Map替换。我新建了一个 support 项目,写了 String FRAGMENT = "android.support.v4.app.Fragment" 并进行 androidx 项目的转换,jetifier 并不会对常量路径进行转换。
然后我我贴一下 Arouter 源码:
如果要想 isSubtype 有效的话,则 fragmentTmV4 返回的就是
androidx.fragment,app.Fragment
了,但 getTypeElement 拿的是 support 的 Fragment,所以,还是有点疑惑在。参考源码: https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-jetifier-release/jetifier/
参考文章: https://yuweiguocn.github.io/migrate-to-androidx/