[Andme系列]基础框架之Application、Activity、Fragment、ViewModel基类封装

2,395 阅读7分钟

原创不易,转载请注明出处;

前言

本篇文章为Andme库功能介绍的第一篇,因此这一段属于个人的口水话,如果赶时间的可以忽视;之后的功能介绍中不再有类似口水话;

BaseAppBaseActivityBaseFragmentBaseViewModel等这类基础结构的封装对整个工程而言非常重要,因为他们在整个工程中所占有的比重非常高。

至于我们为什么要封装,该封装什么内容,该如何去思考这些问题,本身站在我的角度做了说明,但是初次写文,怕口水话太多,导致文章过于拖沓,因此有兴趣的可以入群交流。比如设想一下某天你接到这样一个需求“启动一个Activity时使用一个特定的而非系统默认的动画”。这个需求难么?不难,就是可能很繁琐,因为我们只需要在startActvity之后调用Activity的overridePendingTransition方法即可,如果没有这类封装的存在,那么你的某些头发可能就是因为这些不难却🈶️繁琐的需求消耗掉的。

在进入正题之前,我们先敲下黑板划个重点:

敲黑板:提供自己的统一基类,即便他什么功能都没提供,哪怕Andme已经提供了AMActivity等,都不要直接使用,创建自己的基类继承,也许未来的某一天你会感谢这个做法。

补充:由于功能会不断扩充,所以文章会同步更新,目前介绍的功能并不代表最终的功能。

AMApp基类

AMApp为库提供的Application基类,提供如下功能:

1、前台/后台运行感知

通过一下registerAppStateChangedListener方法注册监听,app从前台切换到后台或者从后台切换到前台时回调此方法注册的回调;调用unregisterAppStateChangedListener方法取消注册;

在程序中可以访问isForeground变量获取当前app状态是否在前台运行;

2、ActivityStack

模仿的Activity栈,可以获取当前运行的Activity以及结束掉指定或者所有Activity的运行等;

AMViewModel基类

AMViewModel为库提供的ViewModel基类,提供如下功能:

1、与Activity/Fragment生命周期方法联动

提供了onResumeonPause等方法,用于ViewModel在对应的生命周期中处理相关的操作,比如释放资源,停止耗时操作等一些操作。

2、支持调用Activity/Fragment支持的常用功能

提供了在ViewModel中调用finishstartActivity等常用方法,不用用户再另行实现,节省时间,如果不够用,可以参照源码进行扩展。

3、统一的对话框交互

用于在ViewModel中直接进行loadingalert等常规操作;目前只提供了基于原生对话框效果的实现和支持,用户可以通过配置实现切换,关于对话框的统一处理,后续会专门围绕如何进行对话框处理,统一UI交互,统一异常处理等话题进行说明;

4、并发、队列等支持(暂未放入,后续专门处理介绍)

ViewModel中处理一些任务时,可能会用到队列,也可能要处理一些并发,这些对于萌新来说很难,但使用AMViewModel来说,这些都不是问题。

关于并发可以查看我曾经写的一个笔记做个简单了解:链接

扩展补充:建议Viewmodel不要持有与ui相关的对象,比如具体的ViewContextActivity等,否则会引起一些意想不到的结果,比如内存泄漏等。

5、Context执行场景

那在ViewModel需要使用Context场景怎么办(也就是要在ViewModel访问Context进行操作)?别担心已经都封装进去了! 只需在ViewModel中调用invokeContextAction方法即可实现。

 fun showAlertDialog(){
    invokeContextAction {
      AlertDialog.Builder(it)
        .setMessage("Hello World.")
        .show()
    }
  }

扩展:聊一聊ViewModel在开发模式中的作用

此处为口水话,赶时间的跳过;

Android开发其实没有非常严苛的开发模式,而且不管是用什么开发模式,我觉得跟开发者的实际应用能力非常有关系,也就是有人用MVC能够写出很好的代码,用MVP也行,而且也能将代码在各种模式之间转换,所以真的不用太关心说一定是按照什么模版去写代码,只要将基础写好了,其他都不是问题。

封装AMViewModel的时候,我其实是不关心最终是使用什么开发模式的,我们要明白的是这些开发模式都需要什么。M不说了吧,它太纯洁了,以至于想法不多,V也不说了吧,可能更多的在layout中呈现这一层内容。

那我们谈什么,谈C?谈P?谈VM?

以前的C可能大家就是把业务逻辑代码写在Activity中罢了,那么现在把逻辑写在ViewModel中不行么?

P层呢?独立出P层,不是也是考虑Activity的角色过于臃肿么,所以想弄个P层分担一下Activity的工作,那这个P是ViewModel不是很合理么!

VM呢?VM如果用一个不太严谨的说法来概括的话,我一直觉得VM只不过是MVP+databinding的效果而已。也就是在某些情况下,我会认为MVVM = MVP+databinding;毕竟MVVM的databinding总需要内容提供吧,而谁提供内容,不也可以是ViewModel么!

所以在我看来,最为核心的就是处理好ViewModel,具体的业务实现放在ViewModel中实现,然后通过LiveData更新视图层,而MVVM只不过可以借助databinding实现自动绑定更新而已,不变的,还是那些业务逻辑和那个ViewModel,所以不管怎么变,核心就是是ViewModel

在一个Android工程项目中,如果没有看到ViewModel我甚至会感觉很不自在。

AMActivity

AMActivity<T>为库提供的Activity基类,提供如下功能:

1、提供主ViewModel

AMActivity会伴随初始化一个AMViewModel作为主要的ViewModel处理业务逻辑

2、分发返回键事件

对返回键的点击事件进行分发,这样便可以在Fragment甚至任何场景中拦截返回键事件处理。

实现原理:Fragment监听返回键的一种合理方式

3、状态栏统一处理(暂未放入,后续专门处理)

半透明/透明状态栏、ViewPager场景等支持

4、其他快捷的工具/扩展函数、变量等

比如提供了activity变量,避免回调中使用this等场景的使用、提供obtainViewModel获取ViewModel

AMFragment

AMFragment为库提供的Fragment基类,提供如下功能:

1、提供主ViewModel

AMFragment会伴随初始化一个AMViewModel作为主要的ViewModel处理的业务逻辑

2、View缓存控制

默认缓存view,如果不需要缓存view,可以重写isEnableViewCache方法返回false即可禁用Fragment缓存View。

3、返回键处理

提供是否拦截返回键点击事件,默认不拦截,重写handleOnBackPressed方法,返回true即可处理返回键点击,方法的参数提供了在非当前代码作用域下调用activity返回键逻辑的支持。

实现原理:Fragment监听返回键的一种合理方式

4、额外的扩展函数支持及其他

比如arguments的读取等,以及还有些功能正在引入中。

以上功能虽然看起来很少很小,但是在实现和选择上,都是经过慎重的考虑,不仅仅是为了实现功能,而是考虑如何更为合理的实现功能。

Sample-来个简单例子

麻雀虽小,五脏俱全,先来写个demo试一下。

//todo 容我想一想,或者你的需求如果跟上面的相关的话,我可以为你重构代码

欢迎入群交流:QQ276097690

更欢迎关注公众号:赶快扫码加入吧

Andme Github地址

如果您有更多的建议或者交流,欢迎入群讨论,添加公众号更能第一时间了解最新内容。