SingletonInstance未赋值?Android单例空指针问题排查
问题分析与解决方案
核心结论
是的,SingletonInstance::set()从未被调用过,这就是触发异常的根源。
问题原因拆解
- 委托仅提供属性逻辑,不自动初始化实例:
ServiceClientCtxConf的伴生对象通过by SingletonInstance()委托实现了ISingletonInstance接口,这仅让ServiceClientCtxConf.instance的get/set操作转发给SingletonInstance类的对应方法,但不会自动创建ServiceClientCtxConf的实例并完成赋值。 - 未执行赋值操作:
你的代码中没有任何地方执行ServiceClientCtxConf.instance = ServiceClientCtxConf(...),导致SingletonInstance内部的singletonInstance始终为null,调用get()时就会触发ConfException: ... is NULL!。
可行解决方案
方案1:手动提前初始化
在应用启动阶段(比如Application的onCreate方法)手动创建实例并赋值:
class MyApplication : Application() { override fun onCreate() { super.onCreate() // 初始化单例实例 ServiceClientCtxConf.instance = ServiceClientCtxConf() } }
方案2:修改SingletonInstance支持懒加载
如果希望单例在第一次被使用时自动创建,可以修改SingletonInstance的实现,传入实例创建逻辑:
interface ISingletonInstance<T> { var instance: T } class SingletonInstance<T : Any>(private val creator: () -> T) : ISingletonInstance<T> { private var singletonInstance: T? = null override var instance: T set(value) { singletonInstance = value } get() = singletonInstance ?: creator().also { singletonInstance = it } } // 对应修改ServiceClientCtxConf的伴生对象: class ServiceClientCtxConf( val serviceClient: IServiceClient = ServiceClient() ) { companion object : ISingletonInstance<ServiceClientCtxConf> by SingletonInstance { ServiceClientCtxConf() } }
方案3:改用Kotlin原生object单例
如果不需要动态修改单例实例(绝大多数单例场景都不需要),直接用Kotlin的object声明更简洁可靠:
object ServiceClientCtxConf { val serviceClient: IServiceClient = ServiceClient() } // 使用时直接调用: ServiceClientConf.setConf(context = ServiceClientCtxConf)
内容的提问来源于stack exchange,提问作者Ralf Wickum
相关产品推荐
相关产品推荐

