You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

迁移至AndroidX后使用YoKeyword Fragmentation遇NoSuchFieldError求助

解决AndroidX迁移后yokeyword.fragmentation的NoSuchFieldError问题

这个问题我之前帮开发者排查过好几次,本质就是AndroidX Fragment版本和yokeyword.fragmentation库的兼容性冲突——旧版本的fragmentation库通过反射直接访问FragmentManagerImpl的私有字段mActive,但这个字段在AndroidX Fragment的后续版本中被修改了(要么改名、要么调整了访问权限),导致运行时找不到该字段抛出错误。

给你几个靠谱的解决办法,按优先级排序:

1. 升级fragmentation到适配AndroidX的最新稳定版

这是最直接有效的方案,官方已经在1.3+版本完成了AndroidX的适配,修复了反射字段的问题。
在你的项目build.gradle(Module级别)中替换依赖为最新版:

// 基础fragmentation库
implementation 'me.yokeyword:fragmentation:1.3.6'
// 如果用到侧滑返回功能,加上这个
implementation 'me.yokeyword:fragmentation-swipeback:1.3.6'

替换完成后,执行Build -> Clean ProjectRebuild Project,清理缓存后重新编译。

2. 对齐AndroidX Fragment的版本

如果升级fragmentation后还是有问题,检查你项目中androidx.fragment:fragment的版本,确保和fragmentation依赖的版本兼容。比如fragmentation 1.3.6和androidx.fragment:fragment:1.2.5是经过验证兼容的,你可以在build.gradle中强制指定这个版本:

implementation 'androidx.fragment:fragment:1.2.5'

避免使用过高版本的Fragment库(比如2.0+),因为这些版本可能对内部结构做了更大的调整,旧版fragmentation还没适配。

3. 手动修改反射代码(不推荐,仅应急用)

如果因为某些原因无法升级库,你可以自己修改FragmentationMagician类中的getActiveFragments方法,改用AndroidX Fragment提供的公开API代替反射访问私有字段。比如把原来的反射代码替换成:

public static List<Fragment> getActiveFragments(FragmentManager fm) {
    List<Fragment> activeFragments = new ArrayList<>();
    List<Fragment> fragments = fm.getFragments();
    if (fragments != null) {
        for (Fragment f : fragments) {
            // 筛选出已添加的活跃Fragment
            if (f != null && f.isAdded()) {
                activeFragments.add(f);
            }
        }
    }
    return activeFragments;
}

这种方法需要你拉取fragmentation的源码修改后重新打包,比较繁琐,所以优先推荐前两种方案。

额外注意事项

  • 迁移AndroidX时,要确保项目中没有混合使用support库和AndroidX库,所有依赖都要切换到AndroidX版本,否则会引发各种兼容性问题。
  • 如果使用了其他第三方库,也要确认它们已经完成AndroidX适配。

内容的提问来源于stack exchange,提问作者Andreas Bagus

火山引擎 最新活动