Android Jetpack 应用指南(二) - ViewModel

简介:

前言

上一篇文章简要概述了LiveData及其简单使用,本篇将会简要讲述AAC的另一个核心组件ViewModel。

与上一篇文章相同,本篇同样是ViewModel的初探,会用尽可能简洁的方式来了解ViewModel,让我们对ViewModel有一个初步印象,不会长篇大论或者源码轰炸,导致干货太多引起阅读困难。

目录

  • ViewModel简介
  • ViewModel生命周期
  • ViewModel使用教程
  • ViewModel注意事项

正文

ViewModel简介

ViewModel是用来保存应用UI数据的类,它会在配置变更(Configuration Change)后继续存在。

为什么需要在Android开发中引入ViewModel类呢?

原因有以下几点:

1.在Android开发中,我们将变量、逻辑和数据都放置在Activity或Fragment中,长此以往不仅导致了Activity和Fragment的代码难以维护,这也违反了单一责任原则。使用ViewModel来保存UI数据,可以分担一部分Activity与Fragment的责任,将原本不堪重负的UI控制器的责任进一步划分出去。

记住一点,任何时候activity或fragment只应该用来显示UI数据和接收用户互动,不要在其中保存、处理任何数据。

2.Activity或Fragment这类应用组件都会受到Configuration Change的影响,例如屏幕旋转的时候,Ativity会被销毁重建,如果数据没有正确的保存并恢复,就有可能丢失,导致UI显示异常甚至是崩溃。将应用所有的UI数据保存在ViewModel中,而不是activity中,这样就能确保数据不会受到 Configuration Change的影响。

ViewModel生命周期

当ViewModel的实例生成后,它会在内存中一直存在,直到它的LifeCycle彻底消失。下面用一张引用自官方文档的图,来说明ViewModel的生命周期。
ViewModel的生命周期
从图中可以看出,在Activity的生命周期onCreate()下创建一个ViewModel,当屏幕旋转(activity rotated)时,Activity会销毁并重新创建,但是ViewModel一直存在,直到Activity结束并被彻底销毁。这意味着ViewModel不会因为它的创建者的配置变化而被销毁。

需要注意的是当Activity的回调onDestroy()时并不代表ViewModel会被销毁。

ViewModel使用流程

ViewModel的使用大致有以下2个步骤:

1.创建一个任意名称的类,一般使用XXXViewModel,继承ViewModel类,然后将原本放置在Activity或Fragment中的变量实例,全部移到ViewModel中。如果和LiveData一起使用的话,就可以创建一个响应式的界面。

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

2.在Activity或Fragment通过ViewModel Provider的框架实用类来获取ViewModel。

class MasterFragment : Fragment() {

    private lateinit var itemSelector: Selector

    private lateinit var model: SharedViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        model = activity?.run {
            ViewModelProviders.of(this).get(SharedViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
        itemSelector.setOnClickListener { item ->
            // Update the UI
        }
    }
}

class DetailFragment : Fragment() {

    private lateinit var model: SharedViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        model = activity?.run {
            ViewModelProviders.of(this).get(SharedViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
        model.selected.observe(this, Observer<Item> { item ->
            // Update the UI
        })
    }
}

上述代码中MasterFragment和DetailFragment中会创建一个完全相同的SharedViewModel实例,通过SharedViewModel的实例,MasterFragment和DetailFragment可以进行数据共享和通信。

使用这种方式有以下几个优点:

  • 1.Activity不需要做任何额外处理,也不需要了解ViewModel的交互方式。

  • 2.Fragment与Fragment有着独立的生命周期,相互之间互不影响,如果一个Fragment被替换了,另一个Fragment依然可以正常工作。

  • 3.Fragemnt之间除了需要连接同一个ViewModel外,不需要做额外的操作,即使一个Fragment被销毁,另一个Fragment也不会受到影响。

ViewModel注意事项

通过上述的简单介绍,我们知道了ViewModel强大之处,但是ViewModel在使用时,也存在一些需要注意的事项:

  • 1.任何时候都不要向ViewModel中传入Context对象

    因为Viewmodel的生命周期比它相关联的Activity和Fragment要长,当你在Viewmodel中存储了一个context,当activity被销毁时,ViewModel就会产生内存泄漏。

  • 2.使用AndroidViewModel延长ViewModel的生命周期

    多数情况下,你并不需要延长ViewModel的生命周期。但是某些情况下,你确实需要一个生命周期更长的ViewModel时,可以使用AndroidViewModel,它的生命周期于Application保持一致,也可以在AndroidViewModel中直接使用application的引用。

  • 3.ViewModel并不能取代onSaveInstanceState

    虽然ViewModel和onSaveInstanceState都可以存储数据用于恢复UI界面,但是二者还是存在这以下不同:

    1.ViewModel可以度过配置变更,可以存储大量数据。

    2.onSaveInstanceState可以度过配置变更和进程关闭,只能存储有限的数据

    也就是说当进程被关闭时,viewModel将会被销毁,而onSaveInstanceState将不会受到影响,一般会在viewModel中存储全部UI数据,而onSvaeInstanceState则只存储可以还原UI状态的最少数据。

总结

本篇文章简述了AAC的另一个核心组件ViewModel,本文的定位是初探,所以ViewModel中一个很重要的Fractory方法,还没有介绍,这部分会在后续的AAC实战中再做讲解。下篇文章,再来我么继续来探索AAC的另一个组件Navigation。

目录
相关文章
|
1天前
|
数据库 Android开发 开发者
构建高效Android应用:采用Kotlin与Jetpack的实践指南
【4月更文挑战第30天】 随着移动开发技术的不断演进,Android平台提供了多种工具和框架以提升应用性能和开发效率。在本文中,我们将深入探讨如何结合Kotlin语言的简洁性和Android Jetpack组件的强大功能来构建一个既高效又可维护的Android应用。通过分析现代Android应用架构的关键要素,我们将展示如何利用Kotlin的特性以及如何整合Jetpack中的LiveData、ViewModel和Room等组件,以实现响应式编程、数据持久化和生命周期管理。
|
2天前
|
存储 缓存 数据库
构建高效Android应用:内存优化策略深度剖析
【4月更文挑战第29天】 在移动开发领域,性能一直是衡量应用质量的关键指标之一。特别是对于Android平台,由于设备硬件配置的多样性,内存管理成为开发者面临的一大挑战。本文将深入探讨Android应用内存优化的有效策略,旨在帮助开发者提升应用性能,减少内存消耗,避免常见的内存泄漏问题。通过对Android内存管理机制的分析与实际案例的结合,我们将提供一系列实用的优化技巧,助力应用在竞争激烈的市场中脱颖而出。
|
2天前
|
移动开发 数据库 Android开发
构建高效Android应用:探究Kotlin协程的优化实践
【4月更文挑战第29天】在移动开发领域,尤其是Android平台上,性能优化一直是开发者关注的重点。近年来,Kotlin语言凭借其简洁性和功能性成为Android开发的热门选择。其中,Kotlin协程作为一种轻量级的并发处理机制,为编写异步代码、网络请求和数据库操作提供了极大的便利。本文将深入探讨Kotlin协程在Android应用中的性能优化技巧,帮助开发者构建更加高效的应用程序。
|
2天前
|
存储 数据库 Android开发
构建高效Android应用:采用Kotlin与Jetpack的实践指南
【4月更文挑战第29天】 在现代移动开发领域,构建一个既高效又稳定的Android应用对于开发者来说是一个持续的挑战。随着技术的不断进步和用户需求的日益增长,传统的开发方法已不足以满足市场的要求。本文将深入探讨如何结合Kotlin编程语言以及Android Jetpack组件,来提升Android应用的性能、稳定性及开发效率。通过分析Kotlin的优势、介绍Jetpack的核心组件,并结合实际案例,我们将展示如何在实际项目中应用这些技术,以期达到优化应用架构、提高代码质量和加快开发流程的目的。
9 1
|
2天前
|
移动开发 API Android开发
Android应用性能优化实战
【4月更文挑战第28天】在移动开发领域,一个流畅的用户体验是至关重要的。对于Android开发者而言,应用的性能优化是一项既挑战性也极其重要的工作。本文将深入探讨Android应用性能优化的多个方面,包括内存管理、UI渲染、多线程处理以及电池效率等,旨在为开发者提供实用的性能提升策略和具体的实施步骤。通过分析常见的性能瓶颈,并结合最新的Android系统特性和工具,我们的目标是帮助读者打造更加高效、响应迅速的Android应用。
|
2天前
|
数据处理 调度 Android开发
构建高效Android应用:探究Kotlin的协程优势
【4月更文挑战第28天】 随着移动应用开发日趋复杂,传统的线程和异步处理模型在处理并发任务时显得笨重且易出错。本文深入分析了Kotlin协程作为一种轻量级线程管理方案的优势,探讨了其在Android应用中实现流畅用户界面和提升性能的潜力。通过对协程原理的剖析以及与现有技术的比较,揭示了如何利用协程优化应用结构、简化代码逻辑,并提高应用的响应性和可维护性。
|
4月前
|
Android开发 开发者
什么是Android Jetpack,它包括哪些组件?
什么是Android Jetpack,它包括哪些组件?
42 0
|
4月前
|
IDE API 开发工具
Google I/O :Android Jetpack 最新变化(四)Compose
Google I/O :Android Jetpack 最新变化(四)Compose
107 0
|
4月前
|
JSON IDE 测试技术
Google I/O :Android Jetpack 最新变化(二) Performance
Google I/O :Android Jetpack 最新变化(二) Performance
114 0
|
4月前
|
SQL API Android开发
Google I/O :Android Jetpack 最新变化(一) Architecture
Google I/O :Android Jetpack 最新变化(一) Architecture
70 0