我一行代码都不写实现Toolbar!你却还在封装BaseActivity?

本文由jessyan投稿。

jessyan的博客地址:

http://www.jianshu.com/u/1d0c0bc634db


这是继我们为什么要把Dagger2,MVP以及Rxjava引入项目中?之后,作者的又一篇文章,文章非常有意思,有空一定想想利用ActivityLifecycleCallbacks能做哪些有趣的事情~


当然了,每个人的看法都不同,本文并不是推荐大家一定要这么做,可以用来扩宽一些思路,那也是极好的~


1

前言


距离 上篇文章 的发表时间已经过去两个多月了,这两个月时间里我没写文章但一直在更新着我的 MVPArms (https://github.com/JessYanCoding/MVPArms)框架,让他逐渐朝着 可配置化集成框架 发展

就在前段时间我在鸿洋公众号上看到了一篇文章,大概是介绍怎么封装 BaseActivity ,让 Activity 通过几行代码就可以实现 ToolBar。


刚好我的 MVPArms 框架也更新了一个功能: 通过非继承 Activity Fragment 来实现以前需要封装进 BaseActivity  BaseFragment 通过继承来实现的一些公共逻辑。


那我就来说说我怎么在不使用继承的情况下让 Activty 一行代码都不写就能实现 Toolbar。


2

为什么我提倡少封装BaseActvity少用继承


BaseActivity 封装多了,除了不好管理外,还有最重要的一点就是, Java 只能单继承,当如果你的 Activity 需要使用到某个三方库,那个三方库必须让你继承于它的 Activity 但是你又需要你自己封装的 BaseActivity 的某些特性,这时你怎么办? 


你不能改三方库的 Activity 所以你只有改你的 BaseActivity 让它去继承三方库的 Activity,但是当改了 BaseActivity 后,发现有很多继承于 BaseActivity 的 Activity 并不需要这个三方库,却被迫继承了它的 Activity ,这时你又要重新封装一个 BaseActivity


当这种情况发生的多了,你的 BaseActiviy 也越来越多,这样就恶性循环了,所以我不仅提倡 App 开发者少封装 BaseActivity 少用继承,也提倡 三方库 开发者少封装 BaseActivity 少用继承,为什么呢?


因为当 App 开发者的 Activity 需要使用到两个三方库,两个三方库都需要继承它的 Activity,这时你让 App 开发者怎么办?


所以作为一个可配置化集成框架作者,我不能让开发者去直接改我的 BaseActivity 我必须通过其他扩展的方式去解决这个问题。


3

进入正题


好了进入正题,要想解决上面提到的问题,我们就要思考我们为什么一定要封装 BaseActivity 通过继承来实现一些 Activity 的公共逻辑,而不能将公共逻辑封装到其他类里面?


答案很简单,因为我们必须使用到 Activity 的一些生命周期,在对应的生命周期里执行对应的逻辑,这个就是我们不能通过封装其他类来实现的原因,找到了问题关键,那我们就从生命周期上下手来解决问题


ActivityLifecycleCallbacks


提到 Activity 的生命周期,这时我就要介绍一个接口了,它叫 ActivityLifecycleCallbacks ,不知道有同学之前了解过它吗?不了解不要紧,我现在来介绍介绍它

ActivityLifecycleCallbacks 是 Application 中声明的一个内部接口,我们来看看它的结构



这个接口有什么用呢?


Application 提供有一个 registerActivityLifecycleCallbacks() 的方法,需要传入的参数就是这个 ActivityLifecycleCallbacks 接口,作用和你猜的没错,就是在你调用这个方法传入这个接口实现类后,系统会在每个 Activity 执行完对应的生命周期后都调用这个实现类中对应的方法,请记住是每个!


这个时候我们就会想到一个需求实现,关闭所有 Activity !你还在通过继承 BaseActivity 在 BaseActivity 的 onCreate 中将这个 Activity 加入集合???


那我现在就告诉你这样的弊端,如果你 App 中打开有其他三方库的 Activity ,这个三方库肯定不可能继承你的 BaseActivity ,这时你怎么办?怎么办?


这时 ActivityLifecycleCallbacks 就派上用场了, App 中的所有 Activity 只要执行完生命周期就一定会调用这个接口实现类的对应方法, 那你就可以在 onActivityCreated 中将所有 Activity 加入集合,这样不管你是不是三方库的 Activity 我都可以遍历集合 finish 所有的 Activity.


4

使用 ActivityLifecycleCallbacks 实现 ToolBar


(1)设置 NoActionBar 主题



(2)创建 ToolBar 的布局并引用


大家不要纠结我的 Toolbar 布局方式,这里只是实现思想,你可以自己改成自己的布局方式



在你需要 Toolbar 的 Activity 布局中 include 上面的布局




(3)实现 ActivityLifecycleCallbacks 并注册给 Application


下面只是对 ToolBar 简单的设置,你可以自己配置更多复杂的功能,你想象力有多丰富,这里就有多强大



(4)在 AndroidManifest.xml 中设置 Label


以后你想让一个 Activity 实现 ToolBar ,只用做两件事情:


1.在布局文件中

<include layout="@layout/include_title"/>


2.在 AndroidManifest.xml 给这个 Activity 设置 Label ,这个 Label 就是标题名

<activity
    android:name=".mvp.ui.activity.SplashActivity"
    android:label="@string/app_name"
    />


再介绍给大家一个全局配置所有 Activity 进入退出过度动画的方法,设置 Theme 属性


在 Activity 中你根本不用继承任何 Activity ,不用写任何一行代码,就可以实现很多繁琐复杂的功能


很多公共逻辑都可以写到 ActivityLifecycleCallbacks 中,只要敢于尝试,你想象力有多丰富,这里就有多强大


5

扩展


因为所有 Activity 在执行对应生命周期时, ActivityLifecycleCallbacks 对应的方法都会被调用,有些 Activity 可能不需要 Toolbar ,比如三方库的 Activity ,虽然在 onActivityCreated 方法中,判断了 ToolBar 的 Id 找不到就不执行设置 ToolBar 的逻辑,但是未免不够优雅


自定义接口


其实我们可以让 Activity 实现对应的自定义接口, 在 onActivityCreated 中 instanceof 这个自定义接口,如果不实现这个自定义接口,就说明不需要设置 ToolBar ,这样就优雅很多.


储存数据


在 ActivityLifecycleCallbacks 中,所有 Activity 执行对应的生命周期后,它对应的方法都会被调用,所以我们必须区分这个 Activity 到底是哪个 Activity ,所以 ActivityLifecycleCallbacks 每个方法都会传入 Activity 做为参数,我们就可以用来区分 Activity.



但是又有一个问题出现这个 ActivityLifecycleCallbacks 是公用的,当一个 Activity 在 onCreate 方法产生了一个对象 ,我们需要在这个 Activity 执行 onDestroy 时用到这个对象,怎么办?


因为每个 Activity 都要产生这个对象,我们不可能把这个对象存储在 ActivityLifecycleCallbacks 中啊。


现在就可以用到 Activity.getIntent 来存储一些数据, Intent 中持有一个 Bundle 对象可以存储一些数据,


6

举个例子


我们需要使用 ActivityLifecycleCallbacks 实现给所有 Activity 执行 ButterKnife.bind(activity)


Bundle 中可以存储 Parcelable 对象



在 ActivityLifecycleCallbacks 执行对应逻辑



7

需要Activity初始化某些事,或者提供某些数据


BaseActivity 有些时候需要,子 Activity 实现某些方法,或者提供某些数据,如需要子 Activity

实现 initView 返回 setContentView() 中的布局 ID ,实现 initData 初始化一些数据,这样就可以不需要 Activity 再重写 onCreate ,达到规范的目的, 这样使用 ActivityLifecycleCallbacks 同样能做到,那我该怎么做呢?


只需要 Activity 实现某个自定义接口

public interface IActivity {

    int initView();

    void initData();

}


然后在 ActivityLifecycleCallbacks 的 onActivityCreated 中调用这些方法,就可以实现



注意事项


由于 ActivityLifecycleCallbacks 中所有方法的调用时机都是在 Activity 对应生命周期的 Super 方法中进行的,所以在 Activity 的 onCreate 方法中使用 setContentView 必须在 super.onCreate(savedInstanceState); 之前,不然在 onActivityCreated 方法中 findViewById 会发现找不到



也可以结合上面的方式使用自定义接口,调用 initView 后,在 findViewById() 找到 ToolBar


一不小心实现了这么多以前必须写到 BaseActivity 中通过继承才能达到的功能,发现没有 BaseActivity ,也并没有什么不舒服的地方,突然感觉自己好牛逼

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值