public void addCallback(LifecycleOwner owner, OnBackPressedCallback onBackPressedCallback)
3、判断是否有启用的回调
public boolean hasEnabledCallbacks()
4、回退事件分发入口
public void onBackPressed()
5、构造器(参数为最终回调)
public OnBackPressedDispatcher(@Nullable Runnable fallbackOnBackPressed) {
mFallbackOnBackPressed = fallbackOnBackPressed;
}
3. OnBackPressedDispatcher 源码分析
OnBackPressedDispatcher 源码不多,我直接带着问题入手,帮你梳理 OnBackPressedDispatcher 内部的实现原理:
3.1 Activity 如何将事件分发到 OnBackPressedDispatcher?
答:ComponentActivity 内部组合了分发器对象,返回键回调 onBackPressed() 会直接分发给 OnBackPressedDispatcher#onBackPressed()。另外,Activity 本身的回退逻辑则封装为 Runnable 交给分发器处理。
androidx.activity.ComponentActivity.java
private final OnBackPressedDispatcher mOnBackPressedDispatcher =
new OnBackPressedDispatcher(new Runnable() {
@Override
public void run() {
// Activity 本身的回退逻辑
ComponentActivity.super.onBackPressed();
}
});
@Override
@MainThread
public void onBackPressed() {
mOnBackPressedDispatcher.onBackPressed();
}
@NonNull
@Override
public final OnBackPressedDispatcher getOnBackPressedDispatcher() {
return mOnBackPressedDispatcher;
}
3.2 说一下 OnBackPressedDispatcher 的处理流程?
答:分发器整体采用责任链设计模式,向分发器添加的回调对象都会成为责任链上的一个节点。当用户触发返回键时,将按顺序遍历责任链,如果回调对象是启用状态(Enabled),则会消费该回退事件,并且停止遍历。如果最后事件没有被消费,则交回到 Activity#onBackPressed() 处理。
OnBackPressedDispatcher.java
// final 回调:Activity#onBackPressed()
@Nullable
private final Runnable mFallbackOnBackPressed;
// 责任链
final ArrayDeque mOnBackPressedCallbacks = new ArrayDeque<>();
// 构造器
public OnBackPressedDispatcher() {
this(null);
}
// 构造器
public OnBackPressedDispatcher(@Nullable Runnable fallbackOnBackPressed) {
mFallbackOnBackPressed = fallbackOnBackPressed;
}
// 判断是否有启用的回调
@MainThread
public boolean hasEnabledCallbacks() {
Iterator iterator = mOnBackPressedCallbacks.descendingIterator();
while (iterator.hasNext()) {
if (iterator.next().isEnabled()) {
return true;
}
}
return false;
}
入口方法:责任链上的每个回调方法仅在前面的回调处于未启用状态(unEnabled)才能调用。
如果如果都没有启用,最后会回调给 mFallbackOnBackPressed
@MainThread
public void onBackPressed() {
Iterator iterator = mOnBackPressedCallbacks.descendingIterator();
while (iterator.hasNext()) {
OnBackPressedCallback callback = iterator.next();
if (callback.isEnabled()) {<