Android中如何检查其他类伴生对象的lateinit变量是否已完成初始化
解决方案
正常情况下Android的Application.onCreate会在所有Activity创建前在主线程同步执行,你遇到的初始化晚于MainActivity请求的问题,大概率是fetchPrefs()或initData()内部存在异步逻辑,没有等待初始化完成就返回了。针对你的需求,有以下几种实现方案:
方法1:直接检查伴生对象的lateinit初始化状态
跨类访问伴生对象的lateinit属性时,需要明确指定伴生对象引用才能调用isInitialized方法,修改MainActivity的checkShifts方法即可:
private fun checkShifts() { // 判断初始化状态,未完成则延迟100ms重试 if (!BaseApp.Companion::apiInterface.isInitialized) { Handler(Looper.getMainLooper()).postDelayed({ checkShifts() }, 100) return } // 原有请求逻辑不变 val checkShiftsApiCall = BaseApp.apiInterface.startRun(BaseApp.userId) checkShiftsApiCall.enqueue(object : Callback<MyAvailableShiftsResponse> { override fun onResponse(call: Call<MyAvailableShiftsResponse>, response: Response<MyAvailableShiftsResponse>) { // 原有业务逻辑 } override fun onFailure(call: Call<MyAvailableShiftsResponse>, t: Throwable) { // 原有异常处理逻辑 } }) }
方法2:修改BaseApp逻辑,从根源避免未初始化问题(更推荐)
不需要每次调用都手动判断状态,通过回调队列自动等待初始化完成:
第一步 修改BaseApp.kt
class BaseApp : Application() { companion object { lateinit var apiInterfaceLogin: ApiInterface // 私有存储实例,对外暴露只读访问 private var _apiInterface: ApiInterface? = null val apiInterface: ApiInterface get() = _apiInterface ?: throw IllegalStateException("ApiInterface未初始化完成") lateinit var okHttpClient: OkHttpClient.Builder // 存储等待初始化完成的任务队列 private val initWaiters = mutableListOf<Runnable>() // 对外提供统一的执行入口,自动判断初始化状态 fun runWhenApiReady(runnable: Runnable) { if (_apiInterface != null) { runnable.run() } else { synchronized(initWaiters) { initWaiters.add(runnable) } } } } override fun onCreate() { super.onCreate() fetchPrefs() initData() // 初始化完成后批量执行所有等待的任务 synchronized(initWaiters) { initWaiters.forEach { it.run() } initWaiters.clear() } } private fun initData() { val interceptor = Interceptor { chain -> val newRequest = chain.request().newBuilder() .addHeader("app-token", Constants.APP_TOKEN) .addHeader("Cache-Control", "no-cache") .build() chain.proceed(newRequest) } okHttpClient = OkHttpClient.Builder() okHttpClient.interceptors().add(interceptor) val client = okHttpClient.build() val retrofit: Retrofit = Retrofit.Builder() .baseUrl(ApiInterface.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(client) .build() _apiInterface = retrofit.create(ApiInterface::class.java) } }
第二步 修改MainActivity的请求逻辑
private fun checkShifts() { BaseApp.runWhenApiReady { val checkShiftsApiCall = BaseApp.apiInterface.startRun(BaseApp.userId) // 原有请求逻辑不变 checkShiftsApiCall.enqueue(object : Callback<MyAvailableShiftsResponse> { override fun onResponse(call: Call<MyAvailableShiftsResponse>, response: Response<MyAvailableShiftsResponse>) { } override fun onFailure(call: Call<MyAvailableShiftsResponse>, t: Throwable) { } }) } }
内容的提问来源于stack exchange,提问作者Pooja Singh
相关产品推荐
相关产品推荐

