* [performReceiveLocked方法的执行过程:](about:blank#performReceiveLocked_83)
* [ActivityThread.java中scheduleRegisteredReceiver方法的执行过程:](about:blank#ActivityThreadjavascheduleRegisteredReceiver_86)
* [LoadedApk.java中InnerReceiver类的performReceive方法的执行过程:](about:blank#LoadedApkjavaInnerReceiverperformReceive_90)
* [LoadedApk.java中ReceiverDispatcher类的performReceive方法的执行过程:](about:blank#LoadedApkjavaReceiverDispatcherperformReceive_93)
* [getRunnable方法的执行过程:](about:blank#getRunnable_97)
=========================================================================
广播的注册分为静态注册和动态注册,静态注册在应用安装时由PMS负责完成注册。
静态注册在应用安装后每一次运行时注册,退出时解除注册。
动态注册需要调用registerReceiver方法,该方法在ContextWrapper.java中实现。
ContextWrapper.java中registerReceiver方法的执行过程:
调用Context对象的registerReceiver方法。
该Context对象为启动ActivityThread时调用createBaseContextForActivity方法返回的ContextImpl对象。
ContextImpl.java中registerReceiverInternal的执行过程:
1.若LoadedApk对象不为null且Context对象不为null,则调用LoadedApk对象的getReceiverDiapatcher方法,获取IIntentReceiver对象。
2.若LoadedApk对象为null或Context对象为null,则创建ReceiverDispather对象,并调用ReceiverDispatcher对象的getIntentReceiver方法,获取IIntentReceiver对象。
3.调用ActivityManager的getService方法,获取AMS代理IActivityManager对象。
4.调用AMS对象的registerReceiver方法,传入IIntentReceiver对象作为参数。
解决了BroadcastReceiver跨进程的问题。
ActivityManangerService.java中registerReceiver方法的执行过程:
1.调用getRecordForAppLocked方法,获取ProcessRecord对象。
该ProcessRecord对象代表请求AMS注册广播的Activity所在的进程。
2.调用IntentFilter对象的actionsIterator方法,获取Iterator对象。
3.迭代Iterator对象,获取String类型的action对象。
根据int类型的uid获取ArrayMap<String,ArrayList>对象,
根据String类型的action对象,获取ArrayList对象,
并把所有的ArrayList对象保存在类型为ArrayList的stickyIntent对象中。
4.从stickyIntent中找出匹配IntentFilter对象的粘性广播的Intent对象,并加入到类型为ArrayList的allSticky对象中。
5.根据IIntentReceiver对象,获取ReceiverList对象,若ReceiverList对象为null,则创建新的ReceiverList对象。
ReceiverList继承自ArrayList,用于存储广播接收者。
6.创建BroadcastFilter对象,传入ReceiverList对象作为参数。
BroadcastFilter用来描述注册的广播接收者。
7.将BroadcastFilter对象添加到ReceiverList对象中。
8.将Broadcast对象添加到IntentResolver对象中。
AMS收到广播时,从IntentResolver对象中找到对应的广播接收者。
============================================================================
广播分为无序广播、有序广播和粘性广播。发送无序广播需要调用sendBroadcast方法,该方法在ContextWrapper.java中实现。
ContextWrapper.java中sendBroadcast方法的执行过程:
调用Context对象的sendBroadcast方法。
该Context对象为启动ActivityThread时调用createBaseContextForActivity方法返回的ContextImpl对象。
ContextImpl.java中sendBroadcast的执行过程:
1.调用ActivityManager的getService方法,获取AMS的代理IActivityManager对象。
2.调用AMS对象的broadcastIntent方法。
ActivityManagerService.java中broadcastIntent方法的执行过程:
1.调用verifyBroadcastLocked方法,验证广播是否合法。
1).验证In.tent对象不为null,且有文件描述符,否则抛出IllegalArgumentException异常。
2).调用Intent对象的getFlags方法,获取Intent对象类型为int的标志。
3).若该标志设置了FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT,则不做处理。
该标志含义为启动检查只接受动态注册的广播接收者。
4).否则若标志没有设置FLAG_ RECEIVER_REGISTERED_ONLY,则抛出IllegalStateException异常。
该标志含义为只接受动态注册的广播接收者。
Android系统为了保护系统的安全,发送广播的Intent必须加上以上两个标志中的一个。
监听Android重要系统广播必须采用动态注册,防止病毒软件的自启动。
2.调用broadcastIntentLocked方法。
broadcastIntentLocked方法的执行过程:
1.将静态注册的广播接收者和动态注册的广播接收者按照优先级高低存储在不同的列表中,再将列表合并。
2.创建BroadcastRecord对象。
3.调用BroadcastQueue对象的scheduleBroadcastsLocked方法。
BroadcastQueue.java中scheduleBroadcastsLocked方法的执行过程:
最后
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
上面分享的腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
【Android高级架构视频学习资源】
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
辄止,不再深入研究,那么很难做到真正的技术提升。**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!