带你领略Android Jetpack组件的魅力
1
前言
最近详细的研究下google推出的框架Jetpack,深感其中的组件的设计之妙,极大的方便了开发者的日常工作,也可以解决很多开发中的问题,对代码的数据逻辑和UI界面深层解耦,实现数据驱动型的ui。
Android Architecture组件是Android Jetpack的一部分,它们是一组库,旨在帮助开发者设计健壮、可测试和可维护的应用程序,包含一下组件:
- 带你领略Android Jetpack组件的魅力 [本文]
- Android Jetpack 架构组件之 Lifecycle(使用篇)
- https://blog.csdn.net/Alexwll/article/details/80638905
- Android Jetpack 架构组件之 Lifecycle(源码篇)
- https://blog.csdn.net/Alexwll/article/details/82491901
- Android Jetpack 架构组件之 ViewModel (源码篇)
- https://blog.csdn.net/Alexwll/article/details/82459614
- Android Jetpack 架构组件之 LiveData(使用、源码篇)
- https://blog.csdn.net/Alexwll/article/details/82996003
- Android Jetpack架构组件之 Paging(使用、源码篇)
- https://blog.csdn.net/Alexwll/article/details/83246201
- Android Jetpack 架构组件之 Room(使用、源码篇)
- https://blog.csdn.net/Alexwll/article/details/83033460
- Android Jetpack 架构组件之Navigation
- https://blog.csdn.net/Alexwll/article/details/83244004
- Android Jetpack架构组件之WorkManger
- https://blog.csdn.net/Alexwll/article/details/83244871
本文是在以上文章完成的基础上,针对每个组件的使用所做的一点思考,个人感觉所有的开发者都应该尽早的熟悉Jetpack组件,相信一定会被它的魅力所吸引,最近也在完成一个使用以上所有组件实现的项目,作为对Jetpack组件的项目实践,后面的文章也会推出,下面按照一个项目的构成来分析一下每个组件对项目开发的帮助
佩服作者!后续也会考虑推送单个组件的使用与原理,也希望大家学起来,学不动扶起来继续学。
2
Android JetPack
对于任何一个产品来说,我们开发中都会面对哪些问题?
如:产品交互、用户体验、代码结构、数据获取、数据存储、网络优化、任务调度等等,虽然在现在的阶段这些问题已经有了很好的解决和优化,也有很多大神的开源组件方便开发者去使用,Android Jetpack就是Google给出的一个官方的处理方法(当然知识处理其中基本问题),Android Jetpack组件的优势:
- 轻松管理应用程序的生命周期
- 构建可观察的数据对象,以便在基础数据库更改时通知视图
- 存储在应用程序轮换中未销毁的UI相关数据,在界面重建后恢复数据
- 轻松的实现SQLite数据库
- 系统自动调度后台任务的执行,优化使用性能
Android Jetpack组件推荐的使用项目架构
上面架构组件的功能如下:
- Activity和Fragment负责产品与用户的交互
- ViewModel作为数据的存储和驱动
- Resposity负责调度数据的获取
- Room储存本地序列化的数据
- Retrofit获取远程数据的数据
按照谷歌推荐的项目架构配合Android Jatpack组件的使用,将会有不一样的开发体验,下面分析每个组件如何帮我们处理这些问题的。
3
Android JetPack 组件介绍
应用程序的开发和产品与用户的交互都是从UI开始的,用户可见的和开发者操作的结果都显示在界面上,所以界面的操作在卡法中占据很重要的地位,也是影响我们开发和使用体验的重要部分,常见的问题如:UI的声明周期处理、数据的显示和刷新、注册监听的释放等, Jetpack架构组件就可以帮我们规范化的解决他们。
Lifecycler
Lifecycler是一个生命周期感知组件,执行操作以响应另一个组件(例如活动和片段)的生命周期状态的更改,简单来说它可以监听活动组件声明周期的变化,在每个声明周期执行相应的方法,不同于以往想在生命周期中执行相应的方法需要设置接口,然后在声明周期中回调接口,这样会造成代码的耦合,也会引发声明周期的问题;
Lifecycler的优点
- Lifecycler实现了执行的逻辑和活动的分离,代码解耦并且增加了代码的额可读性
- Lifecycler在活动结束时自定移除监听,避免了声明周期的问题
Lifecycler的实现主要使用两个主要枚举来跟踪其关联组件的生命周期状态
- Event:从框架和Lifecycle类派发的生命周期事件。 这些事件映射到活动和片段中的回调事件。
- State:由Lifecycle对象跟踪的组件的当前状态。
Lifecycler的原理
Lifecycler为每个活动组件添加了一个没有界面的Fragment,利用Fragment周期会根据活动声明周期变化的特性实现的特性,从而实现声明周期的感知,然后根据注解的Event查找执行相应的方法。
关于Lifecycler的使用和源码请查看一下两篇文章:
- Android Jetpack 架构组件之 Lifecycle(使用篇)
- https://blog.csdn.net/Alexwll/article/details/80638905
- Android Jetpack 架构组件之 Lifecycle(源码篇)
- https://blog.csdn.net/Alexwll/article/details/82491901
LiveData
在产品的开发中我们都已个必要的操作就是数据的更新,当用户执行某正操作或服务器数据发生改变后,都要重新获取数据再次刷新界面的UI,每改变一次就要重复一次,从代码封装的角度,有没有一种工具可以监听数据状态,在数据变化的时候自动更新UI呢?
LiveData就提供了此项更能,从名字中可以看出这个Data时Live的,不是一个死数据,解决了数据展示和刷新的问题
LiveData刷新的使用:
1. 只需创建LiveData实例后,为可观察的数据添加观察者,在数据改变时会自动回调观察者
//创建观察者对象 val nameObservable = Observer<String> { // 创建观察者对象 textView.text = it // 定义onChange()方法中的操作 }
LiveData的几点注意事项:
- 是一个具有声明周期感知特性的可观察的数据保持类,使用LiveData保存数据时,在每次订阅或数据更新时会自动回调设置的观察者从而更新数据,真正的实现了数据驱动的效果
- LiveData 认为观察者的生命周期处于STARTED状态或RESUMED状态下,表示观察者处于活动状态,LiveData只通知活跃的观察者关于更新
- LiveData会在活动处于Destroy时释放观察者,所以开发者无需特别处理
LiveData原理:
内部保存了LifecycleOwner和Observer,利用LifecycleOwner感知并处理声明中期的变化,Observer在数据改变时遍历所有观察者并回调方法
LiveData的使用可源码分析请点击:
- Android Jetpack 架构组件之 LiveData(使用、源码篇)
- https://blog.csdn.net/Alexwll/article/details/82996003
ViewModel
如果你认为上面的方法只是对程序的开发有一点优化的话,那ViewModel的出现确实解决一个简单而又繁琐的问题。
大家都知道用户在使用产品的过程中,可能随时会被中断或界面发生重建,如果数据的丢失会造成很差的用户体验,当然现在都知道在onSaveInstanceState()中保存数据,在界面重建时恢复数据。
这种虽然可以解决问题,但会造成每个界面都要编写板寸和恢复的代码,而且数据量过大时会影响执行性能,VIewModel的出现就是解决这个问题,它会在活动重建时仍然保存数据,在活动创建完成后从中获取数据
ViewModel的生命周期:
- ViewModel对象的范围是在获取ViewModel时传递给ViewModelProvider的Lifecycle生命周期
- ViewModel在内存中直到Activity销毁或Fragment被移除
- 系统首次调用活动对象的onCreate()方法时,通常会请求ViewModel
- 系统可能会在整个活动的整个生命周期中多次调用onCreate(),例如当设备屏幕旋转时
- ViewModel从第一次请求ViewModel直到活动完成并销毁时存在
ViewModel的优点:
- 数据和界面的分离,使数据驱动界面
- 解决了运行中断和界面重建时的数据保存问题
- 配合LiveData实时获取最新数据
- 实现Activity中Fragment之间的数据交互
ViewModel原理:
将数据保存到ViewModel中,然后为活动中添加一个HolderFragment,HolderFragment中保存了ViewStore的实例,ViewStore中使用Map保存了ViewModel,从而在活动重新创建时获取到原来的ViewModel
注:一般时VIewModel和LiveData组合保存可观察的数据
ViewModel的使用可源码分析请点击:
- Android Jetpack 架构组件之 ViewModel (源码篇)https://blog.csdn.net/Alexwll/article/details/82459614
Paging
RecyclerView是项目中展示数据所必不可少的控件,伴随者列表展示而来的就是下拉加载,目前有很多开源的框架已支持下拉加载,主要分两种:
- 当滑动到最后一个Item时,触发加载更多的数据,此时用户会看到加载过程并等待加载完成
- 根据显示的position,在未到最后之前就去加载数据并刷新界面,这样用户可以流畅的滑动下去
Paging的实现和上述原理相似,效果与第二种一致,可以更轻松地在应用程序RecycleView中逐步和优雅地加载数据,看下Paging的实现:
上述组成部分的作用:
- DataSource:数据的来源,需要设置初始化和加载更多的逻辑以及每次加载变化的Key
- PagedList:数据集散中心;根据需要向DataSource索取加载数据,并将得到的数据传递到PagedListAdapter
- PagedListAdapter:数据适配器,这里处了起到普通界面加载适配器的作用外,更重要的是根据滑动显示的坐标,起到了确定什么时候要求向PagedList加载数据
- DiffUtil.ItemCallback:判断数据是否发生改变以相应界面的更新
Paging的好处
- 轻松流畅的实现下拉加载
- 使用LiveData<PagedList>实现数据的可观察
- 配合Room实现数据库的加载和监听
- 支持自定义DataSource
Paging实现的原理:
简单来说就是在PageListAdapter中显示数据,然后根据显示的position确定是否需要加载数据,当触发加载数据时,PagedList调用DataSource中配置的方法加载数据,并将数据传递到Adapter刷新UI
关于Paging组件的使用和源码分析,请点击:
- Android Jetpack架构组件之 Paging(使用、源码篇)https://blog.csdn.net/Alexwll/article/details/83246201
Room
数据库在项目开发中起着至关重要的作用,所有的操作都在修改着数据,而数据的修改驱动UI更新,从而行成了产品的交互;在开发中如果使用Android原生的SQLite数据库,需要编写大量的样板代码,而Room组件可以让你使用几个注解,就可以省略大量的代码,同时支持更强大的数据库访问;
Room提供了三个主要的组件:
- @Database:用来注解类,并且注解的类必须是继承自RoomDatabase的抽象类。该类主要作用是创建数据库和创建Daos
- @Entity:用来注解实体类,@Database通过entities属性引用被@Entity注解的类,并利用该类的所有字段作为表的列名来创建表。
- @Dao:o用来注解一个接口或者抽象方法,该类的作用是提供访问数据库的方法。在使用@Database注解的类中必须定一个不带参数的方法,这个方法返回使用@Dao注解的类
Room使用的优点:
- 样板代码通过注解自动生成,提高开发效率
- 可以返回可观察的数据,在数据库改变时自动更新
- 可以配合Paging使用实现下拉加载
- 支持Cursor和Observable查询
Room的实现原理:
Room的实现原理其实是很多框架的实现方式,是一种代码注解,在编译时自动生成的方式 https://blog.csdn.net/Alexwll/article/details/82852377(Java注解代码生成);如:ButterKnife框架。
关于Room组件的使用和源码分析,请点击:
- Android Jetpack 架构组件之 Room(使用、源码篇)https://blog.csdn.net/Alexwll/article/details/83033460
Navigation
Navigation框架是Jetpack框架中新的组件,也是比较有意思的和创新的框架,它将程序中界面导航想layout文件一样可视化了,在xml中直接可以编辑和修改界面的导航,简化了应用中目标之间导航的实现,如:
在naviagtion.xml文件的design中添加元素并设置导航,下xml中就会自动填充代码:
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/navigation" app:startDestination="@id/blankFragment"> <fragment ....../> <fragment android:id="@+id/blankFragment" android:name="com.example.administrator.navigation.BlankFragment" <action android:id="@+id/action_otherFragment_to_blankFragment"// 在导航时调用此ID设置目的 app:destination="@id/blankFragment" /> </fragment> </navigation>
调用添加的action即可跳转界面实现导航
btnFragment.setOnClickListener { Navigation.findNavController(btnFragment).navigate(R.id.action_blankFragment_to_secondFragment) }
Navigation的优点:
- 项目界面导航可视化
- 简化界面导航的实现过程
关于Navigation的使用,请点击:
- Android Jetpack 架构组件之Navigation
- https://blog.csdn.net/Alexwll/article/details/83244004
WorkManger
WorkManger是Android Jetpack提供执行后台任务管理的组件,它适用于需要保证系统即使应用程序退出也会运行的任务,可以根据需求设定执行任务的条件,如:插入电源、空闲状态。
- 如果程序处于执行状态,WorkManager可以在您应用程序进程的新线程中运行您的任务
- 如果程序未运行,WorkManager会选择一种合适的方式来安排后台任务 ,可能会使用 JobScheduler,Firebase JobDispatcher或AlarmManager
- 所有的操作都有WokManger调度,开发者无需编写其他调度处理
WorkManager的组成:
- Worker:指定需要执行的任务,可以继承抽象的Worker类,在实现的方法中编写执行的逻辑
- WorkRequest:创建任务请求(执行一项单一任务)
- WorkManager:排队和管理工作请求
- WorkStatus:包含有关特定任务的信息
- Constraints:指定对任务运行时间的限制(任务约束)
WorkManager的基本使用:
1. 定义Worker的实现类
class TestWorker(context: Context, workerParameters: WorkerParameters) : Worker(context, workerParameters) { override fun doWork(): Result { Log.e("TestWorker", "执行了 doWork() 操作!") return Result.SUCCESS } }
2. 创建workRequest请求
val workRequest = OneTimeWorkRequest.Builder(TestWorker::class.java).build()
3. 使用WorkManger执行请求
WorkManager.getInstance().enqueue(workRequest)
关于WorkManger的使用,请点击:
- Android Jetpack架构组件之WorkManger
- https://blog.csdn.net/Alexwll/article/details/83244871
好了,Android Jetpack组件介绍完毕了,开篇时还是十一之前,前前后后脱了好久!
本篇是开篇也是入门介绍篇,但确实是在分析和使用了所有组件之后做的一点介绍和总结,当你把Jetpack所有组件联合使用时,你就会发现不一样的妙处,组件之间的联系产生了化学反应,使得整个项目的架构和逻辑清晰明了,项目的运行也变得更加稳定,希望这几篇的学习能对所有想使用Jetpack组件的同学有所帮助!
想深入学习:
- Android Jetpack 架构组件之 Lifecycle(使用篇)
- https://blog.csdn.net/Alexwll/article/details/80638905
- Android Jetpack 架构组件之 Lifecycle(源码篇)
- https://blog.csdn.net/Alexwll/article/details/82491901
- Android Jetpack 架构组件之 ViewModel (源码篇)https://blog.csdn.net/Alexwll/article/details/82459614
- Android Jetpack 架构组件之 LiveData(使用、源码篇)
- https://blog.csdn.net/Alexwll/article/details/82996003
- Android Jetpack架构组件之 Paging(使用、源码篇)
- https://blog.csdn.net/Alexwll/article/details/83246201
- Android Jetpack 架构组件之 Room(使用、源码篇)
- https://blog.csdn.net/Alexwll/article/details/83033460
- Android Jetpack 架构组件之Navigation
- https://blog.csdn.net/Alexwll/article/details/83244004
- Android Jetpack架构组件之WorkManger
- https://blog.csdn.net/Alexwll/article/details/83244871
GoGoGo...
我们项目也规划准备使用上述组件,后续使用了,我也会写点心得分享给大家。