Why does the author design localCacheBillingClient as lateinit?

Viewed 119

The Code A is from the project play-billing-samples, you can see it.

I don't know why the author design localCacheBillingClient as lateinit, it cause the code is little complex, if (::localCacheBillingClient.isInitialized == false) {...} are invoked many times.

I think Code B can works well, right?

Code A

class BillingRepository private constructor(private val application: Application) :
        PurchasesUpdatedListener, BillingClientStateListener {

     lateinit private var localCacheBillingClient: LocalBillingDb


    val subsSkuDetailsListLiveData: LiveData<List<AugmentedSkuDetails>> by lazy {
        if (::localCacheBillingClient.isInitialized == false) {
            localCacheBillingClient = LocalBillingDb.getInstance(application)
        }
        localCacheBillingClient.skuDetailsDao().getSubscriptionSkuDetails()
    }

    val inappSkuDetailsListLiveData: LiveData<List<AugmentedSkuDetails>> by lazy {
        if (::localCacheBillingClient.isInitialized == false) {
            localCacheBillingClient = LocalBillingDb.getInstance(application)
        }
        localCacheBillingClient.skuDetailsDao().getInappSkuDetails()
    }

   fun startDataSourceConnections() {
        Log.d(LOG_TAG, "startDataSourceConnections")
        instantiateAndConnectToPlayBillingService()
        localCacheBillingClient = LocalBillingDb.getInstance(application)
    }
    ...
}

Code B

class BillingRepository private constructor(private val application: Application) :
        PurchasesUpdatedListener, BillingClientStateListener {

    private val localCacheBillingClient: LocalBillingDb by lazy {
         LocalBillingDb.getInstance(application)
    }

    val subsSkuDetailsListLiveData: LiveData<List<AugmentedSkuDetails>> by lazy {
        localCacheBillingClient.skuDetailsDao().getSubscriptionSkuDetails()
    }


    val inappSkuDetailsListLiveData: LiveData<List<AugmentedSkuDetails>> by lazy {
        localCacheBillingClient.skuDetailsDao().getInappSkuDetails()
    }

   fun startDataSourceConnections() {
        Log.d(LOG_TAG, "startDataSourceConnections")
        instantiateAndConnectToPlayBillingService()        
    }
    ...
}
1 Answers

Kotlin - Property initialization using "by lazy" vs. "lateinit"

I believe the answer lies in this thread and precisely below point.

lateinit var can be initialized from anywhere the object is seen from, e.g. from inside a framework code, and multiple initialization scenarios are possible for different objects of a single class. by lazy { ... }, in turn, defines the only initializer for the property, which can be altered only by overriding the property in a subclass. If you want your property to be initialized from outside in a way probably unknown beforehand, use lateinit.

Related