Android Jetpack 架构组件最佳实践

栏目: IOS · Android · 发布时间: 7年前

内容简介:Android Jetpack 是一套组件、工具和指导,可以帮助您快速构建出色的 Android 应用。每个 Jetpack 组件均可单独采用,并且它们依然可以流畅地协作。

Android Jetpack 是一套组件、 工具 和指导,可以帮助您快速构建出色的 Android 应用。

  • Google在17年的I/O大会上推出了架构组件(Architecture Component)工具集。

  • 随后在18年I/O大会上发布了 Android Jetpack ,Jetpack 是Android开发组件工具集,旨在帮助我们轻松构建更稳定、更健壮、以及更可维护的应用程序。

Android Jetpack 架构组件最佳实践

每个 Jetpack 组件均可单独采用,并且它们依然可以流畅地协作。

Jetpack主要分为4个部分, 基础、架构、行为、界面 。从图中得知,Jetpack并不全是些新东西,只要是能够帮助开发者更好更方便地构建应用程序的组件,Google都将其归纳入了Jetpack,可以看出Google对jetpack很重视,对开发者很上心。

  • 紧接着Google推出 AndroidX ,将许多Google认为是正确的方案和实践集中起来。

    • AndroidX 是对support library的重大改进。
    • AndroidX中的所有软件包名都以字符串androidx.开头,位于一致的命名空间中。
    • 与support支持库不同,AndroidX软件包可单独维护和更新。
    • 所有新的支持库开发都将在AndroidX库中进行。

官方推荐架构

Android Jetpack 架构组件最佳实践

使用此架构能带来什么好处?

  • UI和业务逻辑解耦。

  • 有效避免生命周期组件内存泄漏。

  • 提高模块可测试性。
  • 提高应用稳定性,有效降低以下异常发生概率。
    • Can not perform this action after onSaveInstanceState
    • WindowManager$BadTokenException, is your activity running?
    • OOM 、 NullPointerException

测试每个组件

  • 界面和交互:使用 Android 界面插桩测试 。基于此架构只需mock 一个 ViewModel 即可完成界面测试。

  • ViewModel:使用 JUnit 测试 。只需mock一个类,即 Repository

  • Repository:使用 JUnit 测试 。只需mock两个类,XxxDao,XxxService;由于XxxDao,XxxService都是接口,还可以创建虚拟实现来完成复杂测试用例。

  • XxxDao:可以使用插桩测试来测试 DAO 类。这里注意对于每个测试,都请创建内存中数据库以确保测试没有任何副作用(例如更改磁盘上的数据库文件)。

  • XxxService:就Retrofit而言可以使用 MockWebServer 模拟本地服务器。

Lifecycle

Lifecycle是一个类,它包含组件(Activity或Fragment)生命周期状态的信息,并允许其他对象观察此状态。

跟踪组件生命周期

Android Jetpack 架构组件最佳实践

  • Lifecycle内部使用两个主要枚举( EventState )来跟踪其关联组件的生命周期状态。
  • Event :对应Activity或Fragment组件的生命周期回调事件。
  • State :表示被跟踪组件的当前状态,其中 STARTED RESUMED 为活跃状态,可接受到liveData的数据更新。

LifecycleOwner和LifecycleRegistry

  • LifecycleOwner是一个单一的方法接口,表示该类具有生命周期。 support包从26.1.0版本开始,Fragment和Activity就默认实现了该接口。
  • LifecycleRegistry : Lifecycle接口的实现类,协助组件处理生命周期,可处理多个观察者。如果你想自定义LifecyclerOwner请参考support包中Fragment和Activity实现。

ViewModel

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

生命周期

Android Jetpack 架构组件最佳实践

关于ViewModel的生命周期就一句话: 在Activity/Fragment等组件整个生命周期过程中,ViewModel的实例有且只有一个。

这样设计好处在哪呢?

  • 可用ViewModel存储数据,它能安全度过手机旋转等配置变更场景。
  • ViewModel能很好的实现多个Fragment之间的数据共享。

单一责任原则

Android Jetpack 架构组件最佳实践

上图为官方中文视频截图。

  • Actvity或Fragment只显示UI和接收互动。
  • 为避免ViewModel臃肿,可创建presenter处理UI数据。(比如从数据列表中获取某个item的属性)
  • Repository 数据源操作入口。(便于单元测试)
  • 配合其它架构组件使用。

最佳实践

  • 如何时候都不要将Context传入ViewModel。
  • 如果要在ViewModel中使用Application实例,请使用AndroidViewModel子类。
  • ViewModel+LiveData+Databinding 可构建反应式UI。(请查看文末提供的参考资料)
  • ViewModel与onSaveInstanceState要配合使用。

    ViewModel | onSaveInstanceState

    —|—

    能度过配置变更 | 能度过配置变更和进程关闭

    存储大量数据 | 存储少量数据

    | 可序列化

    ViewModel和onSaveInstanceState是相辅相成的,当进程被关闭时,ViewModel会被销毁,而onSaveInstanceState不会受影响。所以用onSaveInstanceState存储少量关键数据(如xxxId),并在该场景恢复后用来加载页面数据。

ViewModel和View之间通信

Android Jetpack 架构组件最佳实践

  • UserProfileActivity引用UserViewModel,可观察其提供的UserLiveData、StatusLiveData、PageStateLiveData数据源变更来刷新UI。
  • 响应用户事件,比如更新用户信息。Activity将更新事件传递给ViewModel,ViewModel有将其委托给Presenter处理,Presenter处理过程及结果通过LiveData与Activity交互。
  • 注意Activity和ViewModel之间是单向引用。 为避免内存泄漏,ViewModel不能持有任何Context引用。

LiveData

LiveData是一个具有生命周期感知特性的可观察的数据保持类。

  • LiveData只通知活跃状态( STARTED or RESUMED )的Observer更新,并在 DESTROYED 状态时自动移除Observer,避免内存泄漏。
  • 始终保持最新数据。举例:1.退后台的Activity在返回前台后会立即收到最新数据。2. 配置变更导致Activity重建后也会立即收到最新数据。
  • 共享资源。单利模式共享同一个LiveData。

LiveData、MutableLiveData、MediatorLiveData区别?

  • 继承关系:MediatorLiveData -> MutableLiveData -> LiveData。 所以MediatorLiveData功能最强大。
  • LiveData 是一个具有生命周期感知的可观察的数据保持类。
  • MutableLiveData 在LiveData基础上打开了修改Value的方法权限。
  • MediatorLiveData 可管理多个LiveData。

Transformations

  • map: 将一种数据类型的

    转换为另一种类型 ```LiveData ```
    // 观察将被转换LiveData ,待其数据源变更后转换为LiveData

    并通知订阅者。

    // 内部使用的MediatorLiveData实现。

    LiveData userLiveData = …;

    LiveData<String> userName = Transformations.map(userLiveData, user -> {
      user.name + " " + user.lastName

    });

    - **switchMap** : 和map类似。差别在于triggerLiveData变更后,会触发和等待另外一个LiveData获取数据。
    

    // 实例代码:将addressInputLiveData转换为postalCodeLiveData.

    class MyViewModel extends ViewModel {

    private final PostalCodeRepository repository;

    private final MutableLiveData

    addressInput = new MutableLiveData();

    public final LiveData postalCode =

    Transformations.switchMap(addressInput, (address) -> {
              return repository.getPostCode(address);
           });
    
    public MyViewModel(PostalCodeRepository repository) {
    this.repository = repository
    }

    // addressInputLiveData变更时触发repository.getPostCode,

    // 待其回去成功后,再将数据设置给postalCodeLiveData。

    private void setInput(String address) {
            addressInput.setValue(address);
        }

    }

    ```

几个问题

LifecycleOwner组件是如何与liveData通信的?

  • SupportActivity 通过添加一个空的ReportFragment来处理生命周期状态变更回调;Fragment则在自身生命周期函数中处理。
  • LifecycleOwner组件,通过LifecycleRegistry类中handleLifecycleEvent -> dispatchEvent方法与liveData通信,从而是liveData具有自动感知组件生命周期的能力。
  • 组件销毁时,LifecycleRegistry会通知liveData移除observer。

ViewModel如何做到一直在内存中,直到Activity销毁或Fragment被移除时才被清除的?

1.x.x版本实现

  • Activity或Fragment会添加一个空的HolderFragment,而ViewModelStore实例被HolderFragment持有,所以就保证了整个生命周期中ViewModelStore实例始终唯一,也就保证了其缓存的ViewModel实例会一直存在直到组件销毁(在onDestroy中会调用ViewModelStore.clear()方法清除其缓存的ViewModel实例)。
  • 由于这个HolderFragment设置了setRetainInstance(true), 这样在Activity重建时它不会执行onDestroy回调,这就是它能度过配置变更的原因

以上所述就是小编给大家介绍的《Android Jetpack 架构组件最佳实践》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTML5

HTML5

Matthew David / Focal Press / 2010-07-29 / USD 39.95

Implement the powerful new multimedia and interactive capabilities offered by HTML5, including style control tools, illustration tools, video, audio, and rich media solutions. Understand how HTML5 is ......一起来看看 《HTML5》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具