简体   繁体   中英

Kotlin lazy usage

I'm currently using Realm in my application, and to make sure i manage Realm instances correctly, i introduced in my base Activity a variable like this:

protected val realm: Realm by lazy {
        Realm.getDefaultInstance()
}

And then in onDestroy i do this:

override fun onDestroy() {
    super.onDestroy()
    realm.close()
}

And then i realised this is a waste. If the current activity doesn't use realm, it will open and immediately close in onDestroy .

So i updated to this:

    private var usedRealm = false

    protected val realm: Realm by lazy {
        usedRealm = true
        Realm.getDefaultInstance()
    }

override fun onDestroy() {
        super.onDestroy()

        if (usedRealm) {
            realm.close()
        }
    }

Is there any way to accomplish the same, without the extra flag?

  1. There is a bug in your current implementation. If Realm.getDefaultInstance() throws then usedRealm will be set to true but the lazy won't actually be initialized (intialization would have failed). You can fix this by only calling usedRealm = true after calling Realm.getDefaultInstance() :

     protected val realm: Realm by lazy { val realm = Realm.getDefaultInstance() usedRealm = true realm } 

    or

     protected val realm: Realm by lazy { Realm.getDefaultInstance().apply { usedRealm = true } } 
  2. You can accomplish the same without the extra flag by keeping a reference to the raw Lazy object itself:

     private val lazyRealm = lazy { Realm.getDefaultInstance() } protected val realm by lazyRealm override fun onDestroy() { super.onDestroy() if (lazyRealm.isInitialized()) { realm.close() } } 

    This still requires an additional field but you no longer have to maintain the initialization state yourself.

  3. You can also use Lazy directly instead of as a delegate :

     protected val lazyRealm = lazy { Realm.getDefaultInstance() } override fun onDestroy() { super.onDestroy() if (lazyRealm.isInitialized()) { lazyRealm.value.close() } } 

    or

     protected val lazyRealm = lazy { Realm.getDefaultInstance() } override fun onDestroy() { super.onDestroy() with(lazyRealm) { if (isInitialized()) { value.close() } } } 

    This makes it so that there is no extra property but Lazy is now part of your API and everywhere where you would have simply referenced realm you now have to reference lazyRealm.value . You get to weigh the pros and cons. :-)

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