栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

by viewModels() 与by activityViewModels()你真的懂了么

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

by viewModels() 与by activityViewModels()你真的懂了么

kotlin中用by关键字来实现委托,委托有类委托,属性委托。标题的 by viewModels 与 by activityViewModels 是用来实现属性委托的。
简单举个类委托的例子:

interface Animal {
    fun do()
}

class Bird(val s: String) : Animal {
    override fun do() { do(s) }
}

class Dog(a: Animal) : Animal by a

fun main() {
    val bird = Bird("bird")
    Dog(bird).do()
}

bird

可以看出,Dog里面没有定义do方法,却可以打印出bird,证明dog把方法委托给了传递进来的bird
重点来了,属性委托。

class Animal {
    val name :String by AnimalDelegate()
}
class AnimalDelegate {
    operator fun getValue(animal: Animal, property: KProperty<*>): String {
        val s = "小猪"
        println("setValue ${property.name} is ${s}")
        return s
    }

    operator fun setValue(animal: Animal, property: KProperty<*>, s: String) {
        println("setValue ${property.name} set to be ${s}")
    }
}

上面的实现了对name的属性委托,注意,被委托的对象,也就是 by后面的,必须实现这两个方法!

    operator fun getValue(animal: Animal, property: KProperty<*>): String {
        val s = "小猪"
        println("setValue ${property.name} is ${s}")
        return s
    }

    operator fun setValue(animal: Animal, property: KProperty<*>, s: String) {
        println("setValue ${property.name} set to be ${s}")
    }

看方法签名,第一个参数为被委托对象所在的类,第二个参数为 KProperty

为什么会讲属性委托?因为 by lazy by viewModels by activityViewModes本质上都是属性委托。
lazy是函数,viewModels是函数,activityViewModels也是函数,他们返回了Delegate 对象。且这个对象必须要有 operator fun getValue operator fun setValue ,用val生命不需要 setValue.
点开viewModels源码,如下

public inline fun  ComponentActivity.viewModels(
    noinline factoryProducer: (() -> Factory)? = null
): Lazy {
    val factoryPromise = factoryProducer ?: {
        defaultViewModelProviderFactory
    }

    return ViewModelLazy(VM::class, { viewModelStore }, factoryPromise)
}

再点

public class ViewModelLazy (
    private val viewModelClass: KClass,
    private val storeProducer: () -> ViewModelStore,
    private val factoryProducer: () -> ViewModelProvider.Factory
) : Lazy {
    private var cached: VM? = null

    override val value: VM
        get() {
            val viewModel = cached
            return if (viewModel == null) {
                val factory = factoryProducer()
                val store = storeProducer()
                ViewModelProvider(store, factory).get(viewModelClass.java).also {
                    cached = it
                }
            } else {
                viewModel
            }
        }

    override fun isInitialized(): Boolean = cached != null
}

再点

public interface Lazy {
    
    public val value: T

    
    public fun isInitialized(): Boolean
}


public fun  lazyOf(value: T): Lazy = InitializedLazyImpl(value)


@kotlin.internal.InlineOnly
public inline operator fun  Lazy.getValue(thisRef: Any?, property: KProperty<*>): T = value

最后一行是关键!用扩展函数声明了 operator getValue 函数。
真相大白。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/893980.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号