Search code examples
javaandroidandroid-contextandroid-broadcastreceiver

How does ContextWrapper.registerReceiver() function works to dynamically register a receiver?


I am currently re-learning one of the components in Android, broadcast receiver.

As we know: registerReceiver(Broadcastreceiver receiver, Intentfilter filter) is used to dynamically register a receiver to AMS. So I CTRL+click this function in Android Studio to see how it works and I get into 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);** }
}

So I click method and get into Context.java. It's an abstract class, all methods remain as abstract methods without implementation logic including registerReceiver. Method codes:

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

So there is no logic showing how a receiver and Intent Filter works to register a broadcast receiver. But I Google it and found others' source code is different from mine: They've got a ContextImpl Class to implement Context class and that makes sense:

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

Click registerReceiverInternal and they get into 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.
}

The main problem is the difference of returning value between two functions: mine is: mBase.registerReceiver() but others' is registerReceiverInternal().

Why my Android package source code is different from his? The most important is: I can still use broadcast receiver in projects without a single problem but how is that even possible if the function call chain leads to an abstract function in the end without implementation logic but still able to use?


Solution

  • Instead of Ctrl+click I would debug the flow and see where it takes you.

    Ctrl+click will always take you to the origin of a method, but because its an abstract class it doesn't know which class that extends it (from all the possible classes that do it) is the one calling the method in that specific moment.