Kotlin使用object实现Application单例出现空指针异常怎么解决
问题根因与解决方案
核心错误原因
- Android系统会在应用启动时自动创建Application子类的全局唯一实例,只有系统创建的这个实例会走完整的生命周期初始化,能拿到有效的
applicationContext。你使用object关键字声明AppController相当于自己额外创建了一个单例实例,该实例没有经过系统初始化流程,调用applicationContext自然返回空值,触发空指针。 - 你将
RequestQueue的初始化放在了类属性初始化阶段,该阶段执行时机远早于Application的onCreate生命周期回调,哪怕是系统创建的Application实例,此时也还没完成context初始化,依然会返回空值。 - 你在Activity类的属性声明处直接调用
AppController.getRequestQueue(),会在Activity类加载阶段就触发AppController实例的初始化,此时系统还没完成Application实例的创建流程,进一步放大了空指针的发生概率。
修复步骤
1. 修正Application类实现
不要用object声明Application子类,依靠系统保证全局单例,通过伴生对象暴露实例:
class AppController : Application() { private lateinit var queue: RequestQueue override fun onCreate() { super.onCreate() // 系统初始化完成后再存实例、初始化请求队列 instance = this queue = Volley.newRequestQueue(applicationContext) } fun getRequestQueue(): RequestQueue = queue companion object { lateinit var instance: AppController private set } }
2. 注册Application到Manifest
在AndroidManifest.xml的application标签中指定自定义的Application类,否则系统不会使用你写的AppController:
<application android:name=".AppController" <!-- 其余原有配置不变 --> > <!-- 原有四大组件配置不变 --> </application>
3. 修正Activity中的调用方式
不要在类属性初始化阶段直接获取请求队列,使用lazy延迟初始化保证取值时Application已经初始化完成:
class MainActivity : AppCompatActivity() { // 懒加载,第一次使用时才取值,此时Application已初始化完成 private val queue by lazy { AppController.instance.getRequestQueue() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 后续需要使用queue的逻辑直接调用即可 } }
内容的提问来源于stack exchange,提问作者Joe Bones
相关产品推荐
相关产品推荐

