简体   繁体   中英

Check if an companion object from another class is initialized before using it

I'm initializing my retrofit client in Base Application android class, and in MainActivity I'm using it to call api. Sometimes, the api call starts before Base class could initialize my retrofit client and it crashes the app. How do I check in MainActivity before making api call that if apiInterface client is initialized or not before making the rest api call?

I know that we can do this to check initialization for lateinit variables in a class.

::variable.isInitialized

But It's not working in this case as I access the static object like this BaseApp.apiInterface Here's my code:

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) {
                }
            }
        })
    }
}

You can expose it using additional property in BaseApp companion:

val isApiInterfaceInitialized get() = ::apiInterface.isInitialized

As a side note, you can access properties of companion objects, but you need to reference them explicitly, for example:

BaseApp.Companion::apiInterface

Still, accessing isInitialized is disallowed from outside the object as this is considered implementation details that apiInterface is lateinit .

Also, the main use case of lateinit is when we are sure that we initialize it before the first use. If you need to always/often check it before use or you use it outside the object, then regular nullable property may be a better choice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM