点击蓝字 轻松关注
最开始,我通过 《我一行代码都不写实现Toolbar!你却还在封装BaseActivity?》(https://juejin.im/post/590f09ec128fe100584ee6b0)这篇文章,介绍了 ActivityLifecycleCallbacks,引起了很多人对这个 API 的关注。
在前几天的文章中,我也多次提到过 ActivityLifecycleCallbacks。
之所以一直提这个 API,是因为,我真心觉得这个 API 牛逼啊,类似于 AOP,侵入性低,可插拔,扩展性又极强,可以用来实现埋点,收集数据,等各式各样的需求。
而且这个 API 门槛低,上手极其简单,不需要像某些 AOP 框架那样,要了解编译期,注解,等各式各样的知识点。
所以我建议大家都可以试试这个 API,很多需求用它实现,说不定会更容易。
下面就来介绍下,我在框架中,运用 ActivityLifecycleCallbacks 的真实案例。
用 ActivityLifecycleCallbacks 代理 Activity 的生命周期,完成一些 BaseActivity 的功能。
MVPArms 作为一个开发框架,需要在 Activity 的一些生命周期中,预处理一些逻辑,而 JAVA 只能单继承,如果这些逻辑全放到 BaseActivity 中,一旦开发者有多个 BaseActivity 需要继承,那就非常麻烦。
最后达到的效果是,通过 ActivityLifecycleCallbacks 和接口的方式,将大部分逻辑抽离出了 BaseActivity,虽然没有完全取代掉 BaseActivity,但是 BaseActivity 里面的逻辑已经非常少,并且简单、易读,如果开发者需要扩展 BaseActivity,也就变得非常容易。
作为框架作者,某一天需要继续扩展一些关于 Activity 的功能,也变得非常容易,因为这里已经和 BaseActivity 解耦,做一些调整并不会直接影响到开发者。
比如这里我就将 ButterKnife 的绑定从 BaseFragment 中抽离了出来,放到了 FragmentLifecycleCallbacks 中,为什么没抽离 BaseActivity 中的 ButterKnife.bind(this) 呢?
是因为,之前其实也抽离出来了,BaseActivity 因此变的十分简洁,但是由于和 setContentView 有关的一些问题,又放了回去,所以就只抽离了 BaseFragment。
这就导致很多人问我,BaseActivity 都有 ButterKnife.bind(this),为什么在 BaseFragment 中没有呢,是不是我忘了绑定。
或者问我,为什么 BaseFragment 没有 ButterKnife.bind(this),ButterKnife 却能正常使用,是不是我施了什么魔法。
是的,我就是通过 ActivityLifecycleCallbacks/FragmentLifecycleCallbacks 在暗中观察,然后偷偷的帮你绑定了,神奇不?
请默默学会这一招,然后秀你同事一脸。
框架通过 ActivityDelegate 和 FragmentDelegate 的实现类来代理 Activity 的生命周期,我可以在框架内部不断扩展 Activity 的逻辑,外部的 BaseActivity 根本无法感知,而且还可以在这里面保存一些变量,这里面可以做的事就挺多了,你完全可以发挥自己的想象力。
通过 ActivityLifecycleCallbacks 实现 ToolBar,这个是在 《我一行代码都不写实现Toolbar!你却还在封装BaseActivity?》(https://juejin.im/post/590f09ec128fe100584ee6b0)中分享过的。
如果你感兴趣可以查看 MVPArms 的源码(https://github.com/JessYanCoding/MVPArms/blob/master/demo/src/main/java/me/jessyan/mvparms/demo/app/ActivityLifecycleCallbacksImpl.java#L48)。
如果你想扩展更多的 ToolBar 属性,可以看这里(https://github.com/JessYanCoding/MVPArms/issues/82)。
有些群友实现了,使用 ActivityLifecycleCallbacks 来右划关闭 Activity 的功能,实现方式应该也是同理,当然还有更多的功能等待你去解锁。
通过 ActivityLifecycleCallbacks 来扩展 RxLifecycle,这个在上周推的文章 《MVPArms 是如何调教 RxLifecycle 的?》中,就已经介绍过了,没看过的朋友赶紧去看看。
这个案例的操作就比较骚了。
我们知道 ActivityLifecycleCallbacks/FragmentLifecycleCallbacks 是全局的,这意味着这个 API 不仅可以监听自己项目中的 Activity/Fragment,同样也可以监听三方库或者系统的 Activity/Fragment,所以我也可以在它们的生命周期中加入一些自己的逻辑。
这时候有一个需求来了,我们不想给所有 Activity/Fragment 都应用同一套逻辑,我们想不同的 Activity/Fragment 应用不同的逻辑,或者只给其中的某几个 Activity/Fragment 应用同一套逻辑,这时该怎么办呢?
在 MVPArms 中,是通过接口来区分不同的 Activity,并应用不同的逻辑的。
比如让某个 Activity 实现 IActivity,在 ActivityLifecycleCallbacks 中 instanceof 就可以区分不同的 Activity,做不同的操作了。
但三方库的代码在云端,我们不能靠修改三方库的代码来实现接口,那我们怎么区分三方库中的某个 Activity,来应用不同的逻辑呢?
这就是我在 AndroidAutoSize 中独创的方式,用它实现了,让三方库中的某个页面,可以取消适配,或者自定义设计图尺寸,神奇不?
其实也很简单,就是 通过类名来区分不同的 Activity。
开发者预先把需要特殊处理的三方库类名,保存进一个容器中,当这个 Activity 启动时,ActivityLifecycleCallbacks 就能获取到这个 Activity 的生命周期,在生命周期方法中能获得这个 Activity 的引用,调用 Activity#getClass() 获得这个类后,再将这个类名传进容器的 contains() 方法,如果返回 true,就说明这个类需要特殊处理,false 就不处理。
如果这个需要特殊处理的类,还需要开发者给他自定义一些参数该怎么办呢?
那也很简单啊,定义一个 Java Bean,里面有一些可以自定义的字段,然后将这个容器升级为 Map 即可,开发者把三方库类名作为 Key,Java Bean 作为 Value 保存进去即可。
然后 ActivityLifecycleCallbacks 中不仅有 contains() 操作,还要加一步 get() 操作,取出这个 Java Bean,然后根据这个 Java Bean,给这个三方库 Activity 应用不同的逻辑即可。
其实,只要我们认真观察,很多看似复杂的框架,其实都是用的最简单,最基础的方式实现的。
所以就像我上篇文章中说的一样,我们缺的不是技能,缺的是,思维,以及持之以恒的决心。
往期精彩:
为什么说 AndroidAutoLayout 的设计有问题?
识别二维码,关注我们
点击“阅读原文”可以查看原文哦。