• 拥抱Jetpack之印象篇


    目录

    前言

    一、什么是Jetpack

    二、Jetpack的优势

    三、Jetpack组件库介绍

    3.1、Navigation

    3.2、Lifecycle

    3.3、ViewModel

    3.4、LiveData

    3.5、Room

    3.6、DataBinding

    3.7、WorkManager


    前言

    正文开始前还得絮叨两句,可以忽略这一段内容,哈哈。。。问个问题:你已经拥抱Jetpack了吗?今天我们就来学习一下Jetpack组件库,今天不做技术讲解,我们只是简单的了解一下什么是Jetpack,所以今天的内容很轻松,大家可以愉快的度过这几分钟的时间啦!

    本文参考资料:慕课网《移动端架构师》课程学习

    官网地址:https://developer.android.google.cn/jetpack

    一、什么是Jetpack

    Jetpack是众多优秀组件的集合,是谷歌推出的一套为开发者逐渐统一开发规范的新的架构。

    谷歌官方对Jetpack的介绍如下:

    Jetpack 是一个由多个库组成的套件,可帮助开发者遵循最佳做法、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码,让开发者可将精力集中于真正重要的编码工作。

    我们需要重要掌握的是Android Architecture Components,简称AAC,即:安卓架构组件,我们可以通过下面一张图大致了解一下:

    二、Jetpack的优势

    • Jetpack提供的众多组件具有基于生命周期感知的能力,可以减少NPE崩溃、内存泄漏及模板代码,可以让我们开发出更加健壮且高质量的应用程序。
    • Jetpack提供的组件可以单独使用,也可以搭配使用,并且搭配Kotlin语言特性可以进一步加速开发。

    三、Jetpack组件库介绍

    下面就简单介绍一下我们平时开发中经常用到的几个组件库:

    3.1、Navigation

    它是为单Activity架构而生的端内路由

    • 特点:Activity、Fragment、Dialog提供路由能力的组件、导航时可携带参数、指定转场动画、支持deepline页面直达、fragment回退栈管理等能力;
    • 缺点:十分依赖xml文件(构建页面导航结构图),不利于模块化,组件化开发。

    添加依赖的方式如下:

    1. implementation "androidx.navigation:navigation-fragment:versionNumber"
    2. implementation "androidx.navigation:navigation-ui:versionNumber"

    路由跳转,可以携带参数,指定转场动画:

    1. NavController navController;
    2. navController.navigate(int resId,Bundle args,NavOptions navOptions);

    deepLink实现页面直达能力:

    navController.handleDeepLink(intent);

    管理Fragment回退栈:

    navController.popBackStack(int destinationId,boolean inclusive);

    3.2、Lifecycle

    它是具备宿主生命周期感知能力的组件

    特点:持有组件(比如:Activity或者Fragment)生命周期状态的信息,并且允许其他对象观察此状态。

    添加依赖的方式如下:

    1. implementation 'androidx.appcompat:appcompat:1.3.0'
    2. // 或者单独引入下面的依赖
    3. implementation "androidx.lifecycle:lifecycle-common:2.5.0"

    经典用法:

    1. // Fragment中实现了Lifecycle
    2. public class Fragment implement xxx,LifecycleOwner{
    3. //该对象内部是key-value的map集合,用来存储注册进去的Observer对象
    4. //会在Fragment的每个生命周期方法中遍历存储的Observer观察者,从而实现分发宿主状态
    5. LifecycleRegistry mLifecycleRegistry;
    6. @Override
    7. @NonNull
    8. public Lifecycle getLifecycle() {
    9. return mLifecycleRegistry;
    10. }
    11. private void initLifecycle() {
    12. mLifecycleRegistry = new LifecycleRegistry(this);
    13. }
    14. }
    15. // 使用方式:任意类实现LifecycleObserver接口,在生命周期方法上添加以下注解即可
    16. class MyLocation implements LifecycleObserver{
    17. @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    18. void onCreate(@NonNull LifecycleOwner owner) {}
    19. @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    20. void onDestroy(@NonNull LifecycleOwner owner){}
    21. }
    22. // 然后在宿主页面订阅
    23. getLifecycle().addObserver(myLocation); //注册观察者,观察宿主生命周期状态

    3.3、ViewModel

    它是具备生命周期感知能力的数据存储组件

    特点:页面配置发生改变时数据不丢失、生命周期感知、数据共享

    添加依赖的方式如下:

    1. implementation 'androidx.appcompat:appcompat:1.3.0'
    2. // 或者单独引入以下组件,通常情况下ViewModel会和LiveData搭配使用
    3. implementation "androidx.lifecycle:lifecycle-viewmodel:2.5.0"
    4. implementation "androidx.lifecycle:lifecycle-livedata:2.5.0"

    ViewModel的数据存储、生命周期感知:

    1. // 创建ViewModel类,并不会感知宿主所有生命周期变化,会感知宿主onDestroy被销毁时状态的变化
    2. class MyViewModel extends ViewModel {
    3. @Override
    4. protected void onCleared() {
    5. super.onCleared();
    6. // 宿主销毁时,会执行到这里,可以自行清理释放资源
    7. }
    8. MutableLiveData userInfoData = new MutableLiveData<>();
    9. public void getUserInfo(LifecycleOwner owner, Observer observer){
    10. userInfoData.observe(owner,observer);
    11. // ......从数据库中查询用户数据
    12. userInfoData.setValue(user);
    13. }
    14. }

    ViewModel数据共享:场景:单Activity多Fragment

    1. // 构建ViewModel实例对象,需要使用ViewModelProvider来获取ViewModel对象
    2. // 如果ViewModelStore中已存在那么就返回公用实例,如果不存在,则使用factory创建并缓存
    3. // 不同fragment当中获取同一个ViewModel实例,从而实现数据共享
    4. class FragmentA extends Fragment{
    5. public void onCreate(Bundle bundle){
    6. MyViewModel viewModel = new ViewModelProvider(getActivity().getViewModelStore(),new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);
    7. }
    8. }

    3.4、LiveData

    它是具备生命周期感知能力的数据订阅、分发组件

    • 特点:支持共享资源、支持黏性事件的分发(后注册的观察者可以接收之前的数据)、不再需要手动处理生命周期(自动和宿主生命周期相关联,当宿主被销毁时它会自动反注册Observer)、确保界面符合数据状态
    • 缺点:黏性事件不支持取消
    1. MutableLiveData liveData = new MutableLiveData<>();
    2. // 注册一个跟宿主生命周期绑定的观察者,宿主销毁会自动解除注册
    3. observe(LifecycleOwner owner, Observersuper T> observer)
    4. // 观察不到宿主生命周期,不会自动解除注册
    5. observeForever(Observersuper T> observer)
    6. // 以下两个方法都是分发数据给所有的观察者
    7. // 只能用在主线程
    8. setValue(T value)
    9. // 子线程,主线程都可以使用
    10. postValue(T value)

    3.5、Room

    它是轻量级orm数据库,本质上是一个SQLite抽象层

    特点:使用更加简单(类似于Retrofit库),通过注解的方式实现相关功能,编译时自动生成实现类impl

    添加依赖的方式如下:

    1. implementation "androidx.room:room-runtime:2.4.2"
    2. annotationProcessor "androidx.room:room-compiler:2.4.2"

    Room数据库读写操作:

    1. // 创建一个操作数据库的实体层
    2. @Dao
    3. public interface UserDao {
    4. @Query("SELECT * FROM user")
    5. List getAll();
    6. @Update
    7. User updateUser(User...users);
    8. @Insert
    9. void insertAll(User...users);
    10. @Delete
    11. void deleteUser(User user);
    12. }
    13. // 创建数据库
    14. @Database(entities = {User.class},version = 1)
    15. public abstract class MyDatabase extends RoomDatabase {
    16. public static MyDatabase myDb;
    17. static {
    18. myDb = Room.databaseBuilder(getApplicationContext(),
    19. MyDatabase.class,"database-name").build();
    20. }
    21. public abstract UserDao userDao();
    22. }
    23. // 通过数据库单例对象,获取userDao数据操作对象,访问数据库
    24. myDb.userDao().getAll();

    3.6、DataBinding

    相信很多人对它都已经是很熟悉了,这里就简单的说一下,它只是一种工具,它解决的是View和数据之间的双向绑定,MVVM是一种架构模式,这两者是有本质区别的。

    特点:数据与视图双向绑定、数据绑定空安全、减少模板代码、释放Activity/Fragment的压力

    开启dataBinding:

    1. android{
    2. ...
    3. dataBinding{
    4. enabled = true
    5. }
    6. }

    布局中绑定数据:

    1. <layout xmlns:android="http://schemas.android.com/apk/res/android"
    2. xmlns:app="http://schemas.android.com/apk/res-auto"
    3. xmlns:tools="http://schemas.android.com/tools">
    4. <data>
    5. <variable
    6. name="user"
    7. type="com.jarchie.foundation.User" />
    8. <import type="com.jarchie.foundation.UserManager" />
    9. data>
    10. <androidx.constraintlayout.widget.ConstraintLayout
    11. android:layout_width="match_parent"
    12. android:layout_height="match_parent">
    13. <TextView
    14. android:id="@+id/tvName"
    15. android:layout_width="200dp" //不能使用动态绑定
    16. android:layout_height="wrap_content"
    17. android:text="@{user.name}" //单向绑定数据变更自动通知UI
    18. android:text="@{user.name+@string/addStr}" //字符串拼接需要引用资源
    19. android:text="@{UserManager.getUsername()}" //调用静态方法,类必须先导入
    20. android:textSize="@{@dimen/16sp}" //资源引用
    21. android:onClick="@{()->UserManager.login()}" //lambda表达式形式实现点击事件
    22. app:layout_constraintBottom_toBottomOf="parent"
    23. app:layout_constraintLeft_toLeftOf="parent"
    24. app:layout_constraintRight_toRightOf="parent"
    25. app:layout_constraintTop_toTopOf="parent" />
    26. <EditText
    27. //双向绑定数据变更自动更新UIUI变更了也能自动更新username的数据,比单向绑定多一个=
    28. android:text="@={user.name}"/>
    29. androidx.constraintlayout.widget.ConstraintLayout>
    30. layout>

    当我们写完了xml布局之后,每一个dataBinding布局都会生成一个由布局文件名称命名的DataBinding类,比如:

    1. ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
    2. binding.tvName.setText("不用写findViewById啦啦啦啦啦");

    3.7、WorkManager

    它是新一代的后台任务管理组件,service能做的事情它都能做

    特点:支持周期性任务调度、链式任务调度、丰富的任务约束条件(比如网络条件必须是wifi的条件下才能执行),即使程序退出,依旧能保证任务的执行

    添加依赖的方式如下:

    implementation "androidx.work:work-runtime:2.7.1"

    执行任务:

    1. // 构建任务
    2. public class DownloadFileWorker extends Worker{
    3. public DownloadFileWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
    4. super(context, workerParams);
    5. }
    6. @NonNull
    7. @Override
    8. public Result doWork() {
    9. return Result.success();
    10. }
    11. }
    12. // 构建执行任务的Request对象
    13. OneTimeWorkRequest request = new OneTimeWorkRequest
    14. .Builder(DownloadFileWorker.class)
    15. .build();
    16. // 把任务加入到任务队列
    17. WorkContinuation workContinuation = WorkManager.getInstance(this).beginWith(request);
    18. workContinuation.then(workB).then(workC).enqueue();

    OK,以上这些组件都是我们平时开发中可能会经常使用到的,其余的组件这里就不再多做介绍了,有需要的大家可以自己到网上搜索一下相关的文章,或者自行到谷歌的官网上学习一下。

    今天的内容就到这里啦,下期再会!

  • 相关阅读:
    SpringMVC第一天
    达梦数据库 优化
    HTTP报文首部
    MySQL之数据库维护
    基于Python实现情感分析实验
    Qt5开发从入门到精通——第五篇四节( 文本编辑器 Easy Word 开发 V1.3详解 )
    JavaScript中的原型链(prototype chain)
    零基础学前端(七)将项目发布成网站
    如何让设计师快速提高设计美感?这5个网站就够了
    Qlik GetFieldSelections 详解(用于返回当前选择项的字符串)
  • 原文地址:https://blog.csdn.net/JArchie520/article/details/126003889