Android _ Jetpack 处理回退事件的新姿势 —— OnBackPressedDispatcher(2)

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()) {<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值