Kotlin 单例模式学习

原文博客地址 https://mp.weixin.qq.com/s/GwpqZpyUcOlgAMQZCJM3UQ
原文作者:承香墨影

无参单例

直接使用 kotlin 的 object ,它是依赖类的初始化锁来保证线程安全。
类的初始化锁(原文有图文详细介绍):即在 Class 被加载后,且被线程使用之前,JVM 会去获取一个锁。这个锁可以同步多个线程对同一个类的初始化,避免多线程调用时,引发线程安全的问题。

object Single{
	fun sayHi()
}

有参单例:

object关键字是不能有构造参数的,而 Android中单例是经常需要传递上下文Context

class Single private constructor(context:Context){
	init{
		// 使用 context 初始化
		context.getString(R.string.app_name)
	}
	companion object : SingletonHolder(::Single)
}

// 封装,双重检查锁 + @Volatile 注解 实现
open class SingletonHolder(creator: (A) -> T) {

    private var creator: ((A) -> T)? = creator

    @Volatile
    private var instance: T? = null

    fun getInstance(arg: A): T {
        val i = instance
        if (i != null) {
            return i
        }

        return synchronized(this) {
            val i2 = instance
            if (i2 != null) {
                i2
            } else {
                val created = creator!!(arg)
                instance = created
                creator = null
                created
            }
        }
    }
}

lazy 单例

委托实现延迟加载,例如Fragment实现单例。
它会在第一次调用 get() 方法时,执行 lazy() 的 lambda 表达式并记录结果,之后再调用 get() 就只会返回之前记录的结果,非常适合延迟初始化的场景。

val lazyValue: String by lazy {
    println("computed!")     // 第一次调用输出,第二次调用不执行
    "Hello"
}

fun main(args: Array) {
    println(lazyValue)   // 第一次执行,执行两次输出表达式
    println(lazyValue)   // 第二次执行,只输出返回值
}

输出结果:
	computed!
	Hello
	Hello

实例:Fragment 单例

class CourseFragment : BaseFragment() {

    companion object {
    	// 写法一
        fun newInstance() = CourseFragment()
        // 写法二:lazy 写法
        val newInstance : CourseFragment by lazy { CourseFragment() }
    }
}

你可能感兴趣的:(Android,Kotlin)