由于Google官网给出的该项目是Kotlin版本,我将其改造成Java版本,供大家学习参考,文末给出下载链接,里面包含了详细的注释说明。
该项目虽然简单,但是用到的知识很多,正所谓麻雀虽小五脏俱全,对于架构和Jetpack学习是个很好的示例,强烈推荐。这里给出的前置知识不是必须掌握,而是掌握会更好的理解,不熟悉也没关系,直接看我的注释说明肯定能懂!
前置知识,项目中用到的Jetpack组件库,LiveData,ViewModel,DataBinding,Navigation,Room,WorkManager……
Navigation主架构:布局(DataBinding),Fragment->VmFactory->VM->Repository->Room(Dao)
Google官方的Jetpack学习项目:
Sunflower-github开源项目,太阳花/向日葵
GardenActivity(主界面,activity_garden.xml)
GardenFragment(我的花园,fragment_garden.xml)
FrameLayout(使用BindingAdapter通过数据监听控制显示/隐藏)
初始化binding
gardenList绑定GardenPlantingAdapter
subScribeUi数据管理
GardenPlantingListViewModelFactory->GardenPlantingListViewModel:observe
ViewModel:LiveData,从GardenPlantingRepository获取数据
Repository:单例,从GardenPlantingDao获取数据
PlantListFragment(植物目录列表,fragment_plant_list.xml)
RecyclerView
初始化binding
plantList绑定PlantAdapter
subScribeUi数据管理
PlantListViewModelFactory->PlantListViewModel:observe
AppDatabase初始化,使用WorkManager从文件将数据添加进Room数据库
ViewModel:LiveData,从PlantRepository获取数据
Repository:单例,从PlantDao获取数据
setHasOptionsMenu,标题栏右侧按钮
PlantDetailFragment(植物详情页面,fragment_plant_detail.xml)
AppBarLayout
NestedScrollView
FloatingActionButton
初始化binding
初始化参数接收plantId
PlantDetailViewModelFactory->PlantDetailViewModel->PlantRepository&GardenPlantingRepository
业务功能、界面逐渐增加,性能可能降低
【没有最好的、只有最适合的模式】
1.MVC
Activity作为控制层Controller,一个类/文件打天下。
Activity显示数据的同时持有数据,高耦合、太臃肿。
Activity不持有数据的话,可能出现数据生命周期与Activity不一致,出现OOM或NullPoint Exception。
小项目,灵活处理,不需要团队配合
2.MVP
Activity只负责View,Presenter层维护逻辑,分层明确
接口过多(接口地狱问题)
一个简单的功能,需要写很多接口,用RxBus(RxJava的封装)建立总线开关处理数据流
工业级项目,业务极其复杂庞大,非App的系统应用。
3.MVVM
Activity只负责View,Presenter换成ViewModel
Model,请求request需要的数据、响应response的数据。包含
- 数据的定义,定义数据结构,方便在不同的角色间传递数据
- 数据的存储,数据库、内存缓存、网络
- 数据的获取,从上面存储中获取
DataBinding实现双向绑定,不需要接口(早期的ObservableFiled相当于现在的LiveData)
MVVM+Jetpack,VM层再次提高稳定性
继承ViewModel库,使用LiveData建立数据驱动模型,保证数据的稳定性,屏幕旋转数据不会重建
抽象的仓库Repository包含数据库db、网络请求……
尽量使用MVVM,多用于大型项目,网易云音乐、新闻客户端,视图画面变化频繁
MVVM+Jetpack+Kt
官方提供的Demo项目比较复杂
http://github.com/android/architecture-components-samples
什么是LiveData?
是一个可以被观察的数据持有类,可以感知并遵循Activity/Fragment等组件的生命周期。
做到仅在组件处于生命周期激活状态时才更新UI数据。
基于Lifecycle观察者模式,管理数据,感知生命周期
setValue()只能在主线程中调用,postValue()可以在任何线程中调用。子线程用handler切换线程实现
不好用的通信框架总结:
1.Handler
系统原生,实现线程间通信
高耦合、不利于维护、容易内存泄漏和NullPointer
2.Broadcast
简单
性能差、传播数据有限、打乱代码的执行逻辑
3.Interface
速度快、容易理解
实现复杂、不利于维护
4.RxBus
效率高、无内存泄漏
基于RxJava,学习成本高且依赖包太大(RxJava2.2M)
5.EventBus
使用简单
混淆问题、无法感知组件生命周期、实现复杂
推荐使用LiveData解决以上所有问题,粘性数据/数据倒灌/灵异事件
简历:研究过Jetpack的WorkManager源码
WorkManager有什么作用?
处理非及时任务,如每天同步一次数据到服务器这种需求,不是及时执行,但是又会保证执行的任务。
Android系统会在系统级别服务中,来判断用户的约束条件,当满足时就会执行任务,
但是触发检测是采用广播的形式处理的,例如网络连接成功就会触发。
WorkManager是如何保证?当App杀死后呢?
WorkManager将用户所有信息保存到数据库,并非内存中,实现了持久性保存,所有App被杀掉后依然可以获取任务信息。
如果一个任务正在执行中突然关机了?
WorkManager.getInstance(this).enqueue();
mWorkTaskExecutor.executeOnBackgroundThread(new ForceStopRunnable(context, this));
会检查之前提交的未完成任务继续执行
参考:
并发:
多线程,研究AsyncTask,过时被取代了,用处不大,研究原理(同理RxJava、ButterKnife)
线程池,Mark课程
画时序图的工具:
Visio ProcessOn StarUML Rose
NDK方向需要掌握的内容:
为什么学习开源框架?
最后给出代码,供大家学习参考:
https://download.csdn.net/download/geofferysun/85683738