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