Android源码剖析:BroadcastReceiver注册过程详细解析

深海探险家 2024-08-24 ⋅ 23 阅读

前言

在Android开发中,我们经常会使用BroadcastReceiver来接收系统或者其他应用发送的广播消息。然而,BroadcastReceiver的注册过程并不是那么容易理解。本文将深入剖析Android源码中BroadcastReceiver的注册过程,帮助读者更好地理解这一关键的组件。

BroadcastReceiver的注册

BroadcastReceiver的注册分为两种方式,一种是在AndroidManifest.xml文件中静态注册,另一种是在代码中动态注册。

静态注册

静态注册是将BroadcastReceiver的声明放在应用的AndroidManifest.xml文件中,示例如下:

<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</receiver>

上述代码将一个名为"MyReceiver"的BroadcastReceiver注册到系统的android.intent.action.BOOT_COMPLETED广播中。当系统发送该广播时,MyReceiver将被调用。

动态注册

动态注册是通过代码的方式,在应用运行时动态地注册BroadcastReceiver。示例代码如下:

MyReceiver receiver = new MyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.BOOT_COMPLETED");
registerReceiver(receiver, filter);

上述代码中,我们创建了一个名为MyReceiver的BroadcastReceiver实例,并将其注册到系统的android.intent.action.BOOT_COMPLETED广播中。

BroadcastReceiver的注册过程

接下来,让我们详细解析一下BroadcastReceiver的注册过程。

静态注册

静态注册的关键是通过解析AndroidManifest.xml文件,将其中声明的BroadcastReceiver注册到系统中。

ActivityThread类的handleBindApplication()方法中,会调用LoadedApk类的makeApplication()方法来加载应用程序的配置信息,其中会解析AndroidManifest.xml文件。

private void handleBindApplication()
{
    // ...
    try {
        // ...
        LoadedApk loadedApk = mResourcesManager.getLoadedApk(appInfo.sourceDir,
                mResCompatibilityInfo);
        // ...
        service = loadedApk.makeApplication(mRestrictedProcesses[0], this);
        // ...
    } catch (Exception e) {
        // ...
    }
    // ...
}

LoadedApkmakeApplication()方法中,会调用parseComponent()方法解析AndroidManifest.xml文件中的组件信息,其中包括BroadcastReceiver。

public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
    // ...
    Application app = null;
    String appClass = null;
    try {
        // ...
        appClass = ai != null ? ai.className : "android.app.Application";
        java.lang.ClassLoader cl = getClassLoader();
        if (!forceDefaultAppClass && ai != null && ai.appComponentFactory != null) {
            app = (Application) cl.loadClass(ai.appComponentFactory).newInstance();
        } else {
            // ...
            app = new Application();
        }
        // ...
    } catch (Exception e) {
        // ...
    }
    // ...
    ArrayList<BroadcastReceiver> receivers = mReceivers.get(app);
    if (receivers == null) {
        receivers = new ArrayList<BroadcastReceiver>();
        mReceivers.put(app, receivers);
    }
    return app;
}

parseComponent()方法中,会调用parseComponentFilters()方法解析BroadcastReceiver的过滤器信息,其中会获取到BroadcastReceiver的IntentFilter实例。

动态注册

动态注册的过程相对比较简单。在ContextregisterReceiver()方法中,会将BroadcastReceiver的实例和IntentFilter注册到系统中。

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
{
    // ...
    return registerReceiver(receiver, filter, null, null);
}

registerReceiver()方法中,会将BroadcastReceiver和IntentFilter打包成ReceiverDispatcher实例,并将其添加到系统的ActivityThreadmRegisteredReceivers集合中。

Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission,
        Handler scheduler) {
    // ...
    IIntentReceiver rd = null;
    if (receiver != null) {
        if (mPackageInfo != null && context != null) {
            // ...
            rd = mPackageInfo.getReceiverDispatcher(receiver, context, mMainThread.getHandler(),
                    mInstrumentation, true);
        } else {
            throw new IllegalArgumentException(
                    "You must register your BroadcastReceiver with registerReceiver()");
        }
    }
    // ...
    intent = mMainThread.getInstrumentation().execStartActivity(
            getOuterContext(), mMainThread.getApplicationThread(), null, null,
            intent, -1, options);
    // ...
    return intent;
}

总结

通过以上分析,我们可以看到BroadcastReceiver的注册过程是在系统的ActivityThread中完成的。静态注册是通过解析AndroidManifest.xml文件,将Receiver信息存储到系统中;而动态注册是通过ContextregisterReceiver()方法将Receiver和IntentFilter打包注册到系统中。这些过程对于我们理解BroadcastReceiver的本质以及应用程序的广播消息处理流程非常重要。

以上就是Android源码剖析:BroadcastReceiver注册过程详细解析的内容,希望对读者有所帮助。如有错误或不足之处,请指正。


全部评论: 0

    我有话说: