前景
本文章都是支持androidx的项目为前提,展开探讨如何让Fragment优雅的拿到Activity的back事件。在androidx以前,大家都是通过接口的形式,让Fragment实现接口,通过activity的manager找到对应fragment,然后在通过接口的返回值决定谁消费back事件。
onBackPressedDispatcher
- 从名字上可以很直观看出,该属性的作用就是系统back的转发器,类似想接受这个事件,就应该把事件交给对应的接受者去消费,当接受者不想继续消费时候,可以把分发开关给关闭。简单介绍后是不是觉的超级简单好用。
如何使用
- 首先第一步你fragment的activity必须是直接或者间接继承ComponentActivity(androidx的类,下面就不重复了哈)。
- 需要处理back事件的fragment给自己的activity的mOnBackPressedDispatcher添加一个OnBackPressedCallback事件。
- 在不需要的时候改变OnBackPressedCallback的开关(enabled属性),取消back事件的分发。
- 搭配LifecycleOwner,妈妈再也不用担心内存泄漏。因为源码注解写着当Lifecycle.State为destroyed时候,callback自动从mOnBackPressedDispatcher的分发列表里面移除。
代码如下:
//activity的回退按钮
private val mBackDispatcher = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
backAction()
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
……
//添加callBack
(activity as FragmentActivity).onBackPressedDispatcher.addCallback(this.viewLifecycleOwner, mBackDispatcher)
}
//不符合处理back事件时候,true:打开分发开关,false:关闭分发开关。
mBackDispatcher.isEnabled = false
注意:友情提醒,这里系统back事件只能被activity的一个fragment消费,就是activity有100个callBack,最后也只会把back事件分发到一个callBack上而已,具体后面源码分析会讲到。
源码分析
OnBackPressedDispatcher类
-
activity里面的分发器的类,内部其实很简单。内部有:runnable、Array数组。array数组肯定是必不可少的啦,做为分发器来说内部必须存储全部的callBack对象。那runnable又是什么呢?这里又要回到ComponentActivity里面看了。
由图一可以看出runnable是一个匿名内部类,主要还是里面run方法里面的ComponentActivity.super.onBackPressed()。学Android都知道这个是把back事件交给系统处理的一个函数调用。那我们再看看activity的onBackPressed方法又做了些什么操作。
由图二又可以看出,所有神秘的操作都包含在了OnBackPressedDispatcher的onBackPressed方法里面了。里面具体做两个事情,相信大家也都能猜到了。一是遍历callBack数组,寻找是否有合适的callBack消耗系统的back事件。二是当一失败后,把back事件传回给系统处理。
最后这里的mFallbackOnBackPressed(runnable)就回到图一初始化这里的runnable的匿名内部类了。所以很多东西都是串联起来的,当你仔细阅读后就会收获到很多知识点。如果后续大家想知道LifecycleOwner如何自动移除分发器的callBack的,评论和我说下,我会补上这部分知识。希望能帮助到大家。