Singleton with argument in Kotlin

前端 未结 5 946
醉酒成梦
醉酒成梦 2020-12-05 23:35

The Kotlin reference says that I can create a singleton using the object keyword like so:

object DataProviderManager {
  fun registerDataProvider(pr         


        
相关标签:
5条回答
  • 2020-12-05 23:45

    Kotlin has a feature called Operator overloading, letting you pass arguments directly to an object.

    object DataProviderManager {
      fun registerDataProvider(provider: String) {
          //
      }
    
      operator fun invoke(context: ApplicationContext): DataProviderManager {
          //...
          return this
      }
    }
    
    //...
    val myManager: DataProviderManager = DataProviderManager(someContext)
    
    0 讨论(0)
  • 2020-12-05 23:55

    With most of the existing answers it's possible to access the class members without having initialized the singleton first. Here's a thread-safe sample that ensures that a single instance is created before accessing any of its members.

    class MySingleton private constructor(private val param: String) {
    
        companion object {
            @Volatile
            private var INSTANCE: MySingleton? = null
    
            @Synchronized
            fun getInstance(param: String): MySingleton = INSTANCE ?: MySingleton(param).also { INSTANCE = it }
        }
    
        fun printParam() {
            print("Param: $param")    
        }
    }
    

    Usage:

    MySingleton.getInstance("something").printParam()
    
    0 讨论(0)
  • 2020-12-06 00:00

    I recommend that you use this form to pass arguments in a singleton in Kotlin debit that the object your constructor is deprived and blocked:

    object Singleton {
    
        fun instance(context: Context): Singleton {
            return this
        }
    
        fun SaveData() {}
    }
    

    and you call it this way in the activity

    Singleton.instance(this).SaveData()
    
    0 讨论(0)
  • 2020-12-06 00:01

    Since objects do not have constructors what I have done the following to inject the values on an initial setup. You can call the function whatever you want and it can be called at any time to modify the value (or reconstruct the singleton based on your needs).

    object Singleton {
        private var myData: String = ""
    
        fun init(data: String)  {
            myData = data
        }
    
        fun singletonDemo() {
            System.out.println("Singleton Data: ${myData}")
        }
    }
    
    0 讨论(0)
  • 2020-12-06 00:02

    There are also two native Kotlin injection libraries that are quite easy to use, and have other forms of singletons including per thread, key based, etc. Not sure if is in context of your question, but here are links to both:

    • Injekt (mine, I'm the author): https://github.com/kohesive/injekt
    • Kodein (similar to Injekt): https://github.com/SalomonBrys/Kodein

    Typically in Android people are using a library like this, or Dagger, et al to accomplish parameterizing singletons, scoping them, etc.

    0 讨论(0)
提交回复
热议问题