首页 > 解决方案 > 在使用之前检查来自另一个类的伴随对象是否已初始化

问题描述

我在 Base Application android 类中初始化我的改造客户端,在 MainActivity 中我使用它来调用 api。有时,API 调用在基类可以初始化我的改造客户端之前开始,它会使应用程序崩溃。如何在进行 api 调用之前检查 MainActivity 是否在进行其余 api 调用之前初始化了 apiInterface 客户端?

我知道我们可以这样做来检查类中 lateinit 变量的初始化。

::variable.isInitialized

但是在这种情况下它不起作用,因为我访问像 BaseApp.apiInterface 这样的静态对象这是我的代码:

BaseApp.kt

 class BaseApp : Application() {   
        companion object {     
            lateinit var apiInterfaceLogin: ApiInterface
            lateinit var apiInterface: ApiInterface   
            lateinit var okHttpClient: OkHttpClient.Builder
        }
       
     override fun onCreate() {
            super.onCreate()
            fetchPrefs()
            initData()
        }
    
     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.kt

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    companion object {
        
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        checkShifts()  
    }

    private fun checkShifts() {
        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) {
                }
            }
        })
    }
}

标签: androidkotlininitializationretrofitokhttp

解决方案


BaseApp您可以使用同伴中的其他属性公开它:

val isApiInterfaceInitialized get() = ::apiInterface.isInitialized

作为旁注,您可以访问伴随对象的属性,但您需要显式引用它们,例如:

BaseApp.Companion::apiInterface

尽管如此,isInitialized还是不​​允许从对象外部进行访问,因为这被认为是实现apiInterface细节lateinit

此外,它的主要用例lateinit是我们确定在第一次使用之前对其进行初始化。如果您需要在使用前始终/经常检查它,或者在对象之外使用它,那么常规可为空的属性可能是更好的选择。


推荐阅读