You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何抑制“Rejecting re-init on previously-failed class”相关NoClassDefFoundError警告

核心结论

AndroidX 注解可以配合简单的类隔离逻辑解决该问题,不需要复杂的反射实现。

具体实现方案

你遇到的ART运行时警告是因为类加载阶段就会解析类字段的类型,哪怕你不会实例化高版本类,只要外部类被加载就会触发该类解析。可以通过高版本API逻辑隔离+AndroidX版本注解的方式解决:

  1. 先确认项目引入AndroidX注解依赖,大部分Android项目默认已引入,若缺失可手动在模块级build.gradle中添加androidx.annotation:annotation依赖即可。
  2. 将所有涉及WifiManager.ScanResultsCallback的逻辑封装到加了版本限定注解的静态内部类中:
    import android.os.Build;
    import android.net.wifi.WifiManager;
    import androidx.annotation.RequiresApi;
    
    public class 你的自定义Wifi管理类 {
        // 其他通用的低版本兼容逻辑
        
        // 仅API30及以上才会加载的内部类
        @RequiresApi(Build.VERSION_CODES.R)
        private static class Api30ScanCallbackHolder {
            public final WifiManager.ScanResultsCallback callback = new WifiManager.ScanResultsCallback() {
                // 实现你的回调逻辑
            };
            
            // 封装该回调相关的注册、注销逻辑
            public void register(WifiManager wifiManager) {
                wifiManager.registerScanResultsCallback(Runnable::run, callback);
            }
            
            public void unregister(WifiManager wifiManager) {
                wifiManager.unregisterScanResultsCallback(callback);
            }
        }
        
        private Api30ScanCallbackHolder api30Holder;
    
        // 对外暴露的初始化方法
        public void init(WifiManager wifiManager) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                api30Holder = new Api30ScanCallbackHolder();
                api30Holder.register(wifiManager);
            } else {
                // 低版本走原有扫描逻辑
            }
        }
    }
    

该方案的原理是静态内部类不会随着外部类的加载而加载,只有第一次调用时才会触发类加载,低版本系统永远不会执行到API30的分支,也就不会触发ScanResultsCallback的类解析,自然不会输出警告。

其他简化方案
  • 若使用Kotlin开发,可以直接对该回调字段加懒加载和版本判断,不需要单独封装内部类:
    private val scanCallback: WifiManager.ScanResultsCallback? by lazy {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            object : WifiManager.ScanResultsCallback() {
                // 实现回调逻辑
            }
        } else null
    }
    
  • 不推荐的简化方案:可以将字段类型声明为Object,高版本使用时再强转,该方案可以消除警告但丢失了编译期类型检查,容易出现运行时异常。

注意:单纯给字段加@RequiresApi注解只能消除Lint编译警告,不会阻止类加载阶段的类型解析,无法消除ART的运行时警告,必须配合版本隔离逻辑使用。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:15:03