Android Kotlin Jetpack之ViewModel

作者: 水天滑稽天照八野滑稽石 | 来源:发表于2019-08-13 23:51 被阅读37次

前言

话说我真是怠惰啊,各种鸽,写jetpack又写设计模式还写个view,各种挖坑,算了,继续慢慢填,这次来聊下ViewModel

ViewModel

在Jetpcak里面,LifeCycles、ViewModel、LiveData这三个是相辅相成的,我个人的理解是ViewModel实现了LifeCycles的功能,也是有生命周期的感知的,而且它的生命周期更广(比Activity还要广)


也正因为如此,所以它也解决了2个问题:
1.当Activity/Fragment被销毁重建时,成员变量被清空(需要用onSaveInstanceState()保存数据恢复什么的)
2.当Activity/Fragment进行异步操作时导致的内存泄漏(虽然没有直接解决,而是提供了onCleared()这个方法让我们去处理)
FBI WARNING

正是因为ViewModel比Activity的生命周期还要长,所以ViewModel如果持有Activity的实例,那肯定要产生内存泄漏的(如果业务需要,使用AndroidViewModel(application))

导入

首先我们要依赖Google仓库,在project -> build.gradle里

  repositories {
        //一般来说自动生成的项目都会默认依赖Google和Jcenter仓库的
        google()
        jcenter()
    }

然后是Module -> build.gradle

dependencies {
    def lifecycle_version = "2.0.0"

    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" // For Kotlin use lifecycle-viewmodel-ktx
    // alternatively - just LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    //     AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // For Kotlin use kapt instead of annotationProcessor
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // For Kotlin use lifecycle-reactivestreams-ktx

    // optional - Test helpers for LiveData
    testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
}

看注释按需导入

使用

简单到爆炸的用法...

class MyViewModel : ViewModel(){
    var name: String = "xiao"
}

在Activity里面调用

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val model = ViewModelProviders.of(this)[MyViewMode::class.java]
        tv.text = model.name
    }
}

可能会遇到的问题, ViewModelProviders.of(this)爆红,这个一般是AndroidX的包引起的,将项目迁移至AndroidX就好了,Refactor -> Migrate to AndroidX

Fragment共享

这个也是ViewModel解决的痛点之一,of方法里面不仅可以传Activity对象,也可以传Fragment对象,所以在同Activity下的不同Fragment,我们可以传入相同的Activity对象来获得实例,以此解决Fragment之间的通讯问题。比起直接弄个全局静态对象来通信算是好太多了


//FirstFragment
class FirstFragment : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_first, container, false)
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val mode = activity?.let { ViewModelProviders.of(it).get(MyViewMode::class.java) }
        text.text = mode.toString()
    }
}
//SecondFragment
class SecondFragment : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_second, container, false)
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val mode = activity?.let { ViewModelProviders.of(it).get(MyViewMode::class.java) }
        text.text = mode.toString()
    }
}

可以看到2个Fragment拿到的是同一个对象


总结

ViewModel其实挺简单的,在我的理解就是一个全局的静态对象,然后又有了生命周期,但其实它带来的是一种新的思想,MVVM,也就是数据驱动,viewModel作为中枢,从数据库获取数据,然后交由liveData通知UI更新,关于liveData,我们下期见

相关文章

网友评论

    本文标题:Android Kotlin Jetpack之ViewModel

    本文链接:https://www.haomeiwen.com/subject/etvohctx.html