首页 > 解决方案 > ContextWrapper.registerReceiver() 函数如何动态注册接收者?

问题描述

我目前正在重新学习 Android 中的组件之一,广播接收器。

众所周知:registerReceiver(Broadcastreceiver receiver, Intentfilter filter)用于向 AMS 动态注册接收器。所以我CTRL在 Android Studio 中单击这个函数来查看它是如何工作的,然后我进入了 ContextWrapper.java:

public class ContextWrapper extends Context { 
    Context mBase;

    public ContextWrapper(Context base) {
        mBase = base; } ...//various of methods

public Intent registerReceiver(
    BroadcastReceiver receiver, IntentFilter filter) {
    return **mBase.registerReceiver(receiver, filter);** }
}

所以我单击方法并进入 Context.java。它是一个抽象类,所有方法都保持为抽象方法,没有实现逻辑,包括 registerReceiver。方法代码:

 public abstract Intent registerReceiver(@Nullable BroadcastReceiver 
                                   receiver,IntentFilter filter);

所以没有逻辑显示接收器和意图过滤器如何注册广播接收器。但我谷歌它,发现其他人的源代码与我的不同:他们有一个 ContextImpl 类来实现 Context 类,这是有道理的:

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
        String broadcastPermission, Handler scheduler) {
    return **registerReceiverInternal**(receiver, getUserId(),
            filter, broadcastPermission, scheduler, getOuterContext());
    }

点击registerReceiverInternal,他们进入 ContextImpl.java:

private Intent registerReceiverInternal(BroadcastReceiver receiver, int 
                                   userId,IntentFilter filter, String 
             broadcastPermission,Handler scheduler, Context context) {
//Implementation logic about how Handler distribute AMS etc.
}

主要问题是两个函数之间返回值的差异:我的是:mBase.registerReceiver()但其他的是registerReceiverInternal()

为什么我的安卓包源码和他的不一样?最重要的是:我仍然可以在项目中使用广播接收器而没有任何问题,但是如果函数调用链最终导致抽象函数没有实现逻辑但仍然可以使用,那怎么可能呢?

标签: javaandroidandroid-contextandroid-broadcastreceiver

解决方案


而不是 Ctrl+单击,我会调试流程并查看它会将您带到哪里。

Ctrl+click 将始终将您带到方法的起源,但由于它是一个抽象类,它不知道扩展它的类(从所有可能的类中)是在特定时刻调用该方法的类.


推荐阅读