android 广播的实现,安卓广播的底层实现原理

本文详细探讨了安卓广播的系统实现原理,包括静态广播、动态广播和粘性广播的注册及发送过程。从PackageManagerService如何扫描和注册静态广播,到ActivityManagerService如何处理动态广播,再到粘性广播的存储与重新发送,以及广播队列的工作方式,揭示了Android系统中广播机制的运作流程。
摘要由CSDN通过智能技术生成

相信广播大家都有用过,也知道安卓广播的一些基础知识,如静态广播、动态广播、粘性广播等等,但相信很多人都不知道系统层面是怎样实现这些广播特性的,这篇文章就让我们来聊一聊安卓广播机制的系统实现原理.

静态广播的注册

静态广播是通过PackageManagerService在启动的时候扫描已安装的应用去注册的.

在PackageManagerService的构造方法中,会去扫描应用安装目录,顺序是先扫描系统应用安装目录再扫描第三方应用安装目录.

PackageManagerService.scanDirLI就是用于扫描目录的方法,由于代码比较少,这里我们直接把它贴了上来:

private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {

String[] files = dir.list();

if (files == null) {

return;

}

int i;

for (i=0; i

File file = new File(dir, files[i]);

if (!isPackageFilename(files[i])) {

continue;

}

PackageParser.Package pkg = scanPackageLI(file,

flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);

if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&

mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {

file.delete();

}

}

}

private static final boolean isPackageFilename(String name) {

return name != null && name.endsWith(".apk");

}

可以看到,它通过File.list方法列出目录下的所有后缀为".apk"的文件传给scanPackageLI去处理.

而scanPackageLI(File scanFile,int parseFlags, int scanMode, long currentTime, UserHandle user)内部会调用它的重载方法scanPackageLI(PackageParser.Package pkg,int parseFlags, int scanMode, long currentTime, UserHandle user):

private PackageParser.Package scanPackageLI(File scanFile,int parseFlags, int scanMode, long currentTime, UserHandle user) {

...

final PackageParser.Package pkg = pp.parsePackage(scanFile,scanPath, mMetrics, parseFlags);

...

PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime, user);

...

}

在这个scanPackageLIl里面会解析Package并且将AndroidManifest.xml中注册的BroadcastReceiver保存下来:

...

N = pkg.receivers.size();

r = null;

for (i=0; i

PackageParser.Activity a = pkg.receivers.get(i);

a.info.processName = fixProcessName(pkg.applicationInfo.processName,

a.info.processName, pkg.applicationInfo.uid);

mReceivers.addActivity(a, "receiver");

...

}

...

所以从上面获取静态广播的流程可以看出来:系统应用的广播先于第三方应用的广播注册,而安装在同一个目录下的应用的静态广播的注册顺序是按照File.list列出来的apk的顺序注册的.他们的注册顺序就决定了它们接收广播的顺序.

通过静态广播的注册流程,我们已经将静态广播注册到了PackageManagerService的mReceivers中,而我们可以使用PackageManagerService.queryIntentReceivers方法查询intent对应的静态广播

public List queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId) {

if (!sUserManager.exists(userId)) return Collections.emptyList();

ComponentName comp = intent.getComponent();

if (comp == null) {

if (intent.getSelector() != null) {

intent = intent.getSelector();

comp = intent.getComponent();

}

}

if (comp != null) {

List list = new ArrayList(1);

ActivityInfo ai = getReceiverInfo(comp, flags, userId);

if (ai != null) {

ResolveInfo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值