《深入理解 Android》笔记:ActivityManagerService

《深入理解 Android》笔记:ActivityManagerService

ActivityManagerService 概述:

  • ActivityManagerService负责四大组件的启动/切换/调度、进程的管理/调度等;

  • ActivityManagerService继承自 ActivityManagerNative类,并实现了 Watchdog.MonitorBatteryStatsImpl.BatteryCallback接口;而 ActivityManagerNative继承自 Binder类,并实现了 IActivityManager接口;

  • 客户端使用的是 ActivityManager类,其内部通过调用 ActivityManagerNative.getDefault()得到一个 ActivityManagerProxy对象,通过它与 ActivityManagerService通信;

system_server 对 ActivityManagerService 的初始化:

  • 调用 ActivityManagerService.main()方法,返回 Context对象;

  • 调用 ActivityManagerService.setSytemProcess(),将 system_server进程加入 ActivityManagerService,便于后者管理;

  • 调用 ActivityManagerService.installSystemproviders(),将 SettingsProvider放到 system_server进程中运行;

  • 调用 ActivityManagerService.self().setWindowManager(),在内部保存 WindowManagerService

  • 调用 ActivityManagerNative.getDefault().showBootMessage(),显示启动信息;

  • 调用 ActivityManagerService.self().systemReady(),在传入的 Runnable对象的 run()方法中:

    1. 调用 startSystemUi(),启动系统 UI;

    2. 调用 Battery、Network 等模块的 systemReady()

    3. 启动 Watchdog

ActivityManagerService::main():

  • 创建 AThread线程对象:

    1. 设置线程优先级为 THREAD_PRIORITY_FOREGROUND

    2. 创建 ActivityManagerServive对象:

      1. 创建 /data/system/ 目录;

      2. 创建 BatteryStatsServiceUsageStatsService

      3. 读取 OpenGL、及资源配置信息 Configuration

      4. 读取并解析 /proc/stat 文件中的 CPU 和内存信息、/data/system/packages-compact.xml 文件中的需要考虑屏幕尺寸的 APK 信息;

      5. 调用 Watchdog.getInstance().addMonitor()将自己加入监控;

      6. 创建 mProcessStatsThread线程,用于定时更新系统信息,和 mProcessStats交互;

  • 调用 ActivityThread.systemMain()方法返回 ActivityThread对象:

    1. 调用 HardwareRenderer.disable(true)禁用硬件渲染;

    2. 创建 ActivityThread对象,并调用其 attach(true)方法,

  • 调用 ActivityThread.getSystemContext()得到 Context对象;

  • 创建用于管理 Activity启动和调度的核心类 ActivityStack对象;

  • 调用 BatteryStatsServiceUsageStatsServicepublish()方法;

  • 调用 ActivityManagerService.startRunning(),主要调用 systemReady()

ActivityThread:

  • ActivityThread代表一个应用进程的主线程(其 main方法由所在进程的主线程执行),其职责为调度和执行运行在主线程的四大组件;

  • 通过 ActivityThread可以把 Android 系统提供的组件之间的交互机制和接口(如 Context)也扩展到 system_server中使用;实际上 system_server可以看作一个特殊的应用进程(framework-res.apk 和 SettingsProvider.apk 都运行在该进程中);

  • attach(true)对系统进程的处理:

    1. 创建 Instrumentation工具类对象,它通过 AndroidManifest.xml 中的标签描述,用于监控与其他组件的交互;

    2. 创建 ContextImpl对象,并调用其 init()方法; Context是一个可以操作 Application及其中四大组件的接口;

    3. 调用 Instrumentation.newApplication()创建 Application对象;它是可以看作一个四大组件的容器, ActivityManagerService内部通过 mAllApplications保存所有 Application

    4. 调用 Application.onCreate()

    5. 调用 ViewRootImpl.addConfigCallback(),响应 onConfigurationChanged()onLowMemory()onTrimMemory()等方法;

  • getSystemContext()

    1. 调用 ContextImpl.createSystemContext()创建 ContextImpl对象;

    2. 创建 LoadedApk对象,传入的 package参数为 "android",即代表 framework-res.apk,相当于读取系统资源;

    3. 调用 ContextImpl.init()方法,并传入上面的 LoadedApk对象,相当于加载系统资源;

    4. 调用 ContextImpl.getResources().updateConfiguration(),初始化屏幕等配置信息;

IApplicationThread 和 ActivityThread:

  • IApplication定义了 ActivityManagerService和其他应用进程进行 Binder通信的接口: scheduleLaunchActivity()schedulePauseActivity()scheduleStopActivity()等;

  • ActivityThread通过成员变量 mAppThread指向其内部类 ApplicationThread,而它继承自 IApplicationThread的实现类 ApplicationThreadNative

  • ActivityManagerService通过 IApplication定义的接口向 ActivityThread所在线程发消息,进而控制 Activity执行相关回调;

Context 家族:

  • Context: 抽象类,提供了一组通用的 API;

  • ContextIml: 实现了 Context类的功能, 大部分功能都是直接调用其属性 mPackageInfo去完成;

  • ContextWrapper: 对 Context类的包装,该类的构造函数包含一个的 Context引用,即 ContextIml对象;

  • ContextThemeWrapper: 该类内部包含 Theme 相关的接口,即 android:theme属性指定的。只有 Activity需要主题, Service Application不需要主题,所以 Service/ Application直接继承于 ContextWrapper类;

  • Context实例个数 = Service个数 + Activity个数 + 1( Application对应的 Context实例);

ActivityManagerService::setSystemProcess():

  • 调用 ServiceManager.addService()注册几个服务:

    1. ActivityManagerService

    2. MemBinder:用于打印内存信息;

    3. GraphicsBinder:用于输出应用进程使用硬件显示加速的信息,Android 4.0 新增的服务;

    4. CpuBinder:CPU 信息;

    5. PermissionController:权限管理服务;

  • 调用 context.getPackageManager().getApplicationInfo()查询包名为 androidApplicationInfo对象;

  • 调用 ActivityThread.installSystemApplicationInfo()注册上面查询到的 ApplicationInfo对象:

    1. 调用 ActivityThread.getSystemContext()返回之前初始化过的 Context对象;

    2. 调用 context.init(new LoadedApk())再次初始化;注意之前初始化传入的最后一个参数为 null,这次传入的是上面查询到的包名为 androidApplicationInfo对象;

    3. 创建 Profiler对象,用于性能统计;

  • 调用 ActivityManagerService.newProcessRecordLocked()创建用于保存进程信息的 ProcessRecord对象:

    1. 获取 BatteryStatsService对象,并创建一个耗电量统计项;

    2. 创建 ProcessRecord对象:

      1. 初始化 BatteryStatsServiceApplicationInfoProcessNameIApplicationThread等成员变量;

      2. 初始化 maxAdjhiddenAdj curRawAdjcurAdj等和进程调度和内存管理相关的变量;

      3. 对于 system_server进程, ActivityManagerService还进行了特殊处理:

        1. 将其 persisten设为 true,被 kill 后会重建;

        2. pid设为 MY_PID,即 system_server进程号;

        3. processName设置为 system

        4. maxAdj设置为最大值 SYSTEM_ADJ

  • ActivityManagerService内部通过 mProcessNames保存所有进程名,调用 put()保存上面创建的 ProcessRecord

  • 调用 ActivityManagerService.updateLruProcessLocked(),根据系统当前状态调整进程调度优先级和 OOM_Adj;

ActivityManagerService::installSystemProviders():

  • mProcessNames取出 processName 为 system且 uid 为 SYSTEM_UIDProcessRecord,即 system_server对应的进程;

  • 调用 ActivityManagerService.generateApplicationProvidersLocked()返回 List<ProviderInfo>对象:

    1. 根据进程名和 uid,调用 PackageManagerService.queryContentProviders()查询符合条件的 List<ProviderIndo>

    2. 遍历 List<ProviderInfo>根据包名和 ApplicationInfo查询(如果不存在则构造)并保存 ContentProviderRecord

    3. 调用 ensurePackageDexOpt()执行 dex 优化;

  • providers中去除非系统 Provider;

  • 调用 ActivityThread.installSystemProviders(),将 providers安装到 system_server进程:

    1. 调用 installProvider()得到一个 IContentProvider对象;

      1. 找到 Provider对应的 Context,并调用 Context.getClassLoader()、通过反射生成 ContentProvider实例;

      2. 调用 IContentProvider.asBinder.linkToDeath()

      3. 创建 ProviderClientRecord对象,并保存到 mLocalProviders

    2. 创建 ContentProviderRefCount对象对 ContentProvider进行引用计数控制,引用数为 0 则从系统注销;

    3. 调用 ActivityManagerService.publishContentProviders()

      1. 根据调用者的 pid 找到对应的 ProcessRecord

      2. ProcessRecordpubProviders中找到对应的 ContentProviderRecord,如果找到则以 authority 为 key 保存;

      3. 移除 mLaunchingProviders中保存的处于启动状态的 Provider,并调用 notifyAll()通知等待它们启动的进程;

      4. 调用 updateOomAdjLocked()调整 oom_adj;

  • 创建 CoreSettingsObserver对象,监听 Settings 数据库 secure 表的变化;

  • 调用 UsageStatsService.monitorPackages()

ContentProvider:

  • ContentProvider本身只是一个容器,跨进程调用的支持是通过 Transport实现的; TransporBinder的子类 ContentProviderNative派生;

  • ContentProviderNative实现了 IContentProvider接口,其内部类 ContentProviderProxy供客户端使用;

  • ContentProvidergetIContentProvider()返回 Transport对象;

  • 系统提供 ComponentName 和 authority 两种方式找到 ContentProvider,所以 ActivityManagerService存在对应的两个变量: mProvidersByClass mProvidersByName

ContentProviderRecord:

  • ContentProviderRecord继承自 ContentProviderHolder,内部保存了 ProviderInfo、该 Provider 驻留进程的 ProcessRecord、以及使用该 Provider 的客户端所在进程的 ProcessRecord

  • ActivityManagerServicemProviderByClass成员和 ProcessRecordpubProviders成员均以 ComponentName 为 key 来保存对应的 ContentProviderRecord

ProviderClientRecord:

  • ProviderClientRecordActivityThread提供的用于保存 ContentProvider信息的结构;

  • 内部主要成员:

    1. mLocalProvider用于保存 ContentProvider对象;

    2. mProvider用于保存 IContentProvider对象(即 Transport对象);

    3. mName用于保存该 ContentProvider的一个 authority;

ActivityManagerService::systemReady():

  • 准备 PRE_BOOT_COMPLETED广播,向 PackageManagerService查询接收者,为最后一个接收者注册回调(用来显示启动消息等),最后发送广播;

  • 杀掉那些在 ActivityManagerService还未启动完成就已经先启动的应用进程(一般 Native 进程是不会向它注册的);

  • 从 Settings 数据库获取配置信息:

    • debug_app: 需要 debug 的 APP 名称;

    • wait_for_debugger:表示需要等待调试器,否则直接启动;

    • always_finish_activities: 当一个 Activity不再有地方使用时是否立即执行 destroy;

    • font_scale: 控制字体放大倍数(Android 4.0 新增);

  • 调用传入的 Runnable类型的 goingCallback参数的 run()

    1. 调用 startSystemUi(),启动 SystemUIService(实现了系统状态栏);

    2. 调用 Battery、Network 等其他模块的 systemReady(),启动 Watchdog

  • 启动 persistent为的 APK 进程(排除掉包名为 android的 framework-res.apk,因为它之前已经被启动);

  • 调用 startHomeActivityLocked()启动 Home 界面;

  • 调用 finishBooting()

    1. 注册 PACKAGE_RESTART 的 BroadcastReceiver处理包重启;

    2. 启动那些等待启动的进程;

    3. 每隔 15 分钟检查一次各应用进程用电情况,杀掉使用 Wakelock时间过长的进程;

    4. 调用 SytemProperties.set()设置 sys.boot_completed属性为;

    5. 发送 ACTION_BOOT_COMPLETED广播;

ActivityStack、ActivityRecord、TaskRecord:

  • ActivityRecordtask变量指向该 Activity所在的 Task; state变量表示 Activity状态;

  • ActivityStackmMainStack表示是否是主 Stack,由于目前只有一个 ActivityStack,所以该变量值为 true

  • ActivityStackmHistory成员是 ArrayList类型,用于保存系统中所有 ActivityRecord

  • ActivityStack没有变量保存所有 TaskRecord

ActivityStack::startActivityMayWait():

  • PackageManagerService查询匹配传入的 IntentActivityInfo

  • 获取 Binder调用方 uid 和 pid;

  • 调用 startActivityLocked()返回启动结果 res

    1. 如果调用者不为空,则调用 ActivityManagerService.getRecordForAppLocked()得到它的 ProcessRecord;如果 ProcessRecord为空(该进程没有在 ActivityManagerService注册),则返回 START_PERMISSION_DENIED错误;

    2. 声明两个 ActivityRecord类型的变量 sourceRecord(启动目标 Activity的那个 Activity)和 resultRecord(接收启动结果的 Activity,即处理 onActivityResultActivity);一般情况下,二者指向同一个 Activity

    3. 读取 Intentflags,检查 err是否为,检查权限信息;

    4. ActivityManagerService设置一个 IActivityController类型的监听者(主要用于 Monkey 测试);

    5. 创建 ActivityRecord对象;

    6. 调用 ActivityManagerService.checkAppSwitchAllowedLocked()检查调用建成是否有权限切换应用,如果没有权限,则保存到 ActivityManagerServicemPendingActivityLaunches变量;

    7. 调用 ActivityManagerService.doPendingActivityLaunchesLocked()启动处于 pending 状态的 Activity

    8. 调用 startActivityUncheckedLocked()完成本次启动请求;

  • 如果 Configuration有变化,调用 ActivityManagerService.updateConfigurationLocked()

  • 处理启动结果;

ActivityStack::startActivityUncheckedLocked():

  • 判断是否需要创建新的 Task,以下两种情况需要在 Intentflags附加 Intent.FLAG_ACTIVITY_NEW_TASK

    • 发起请求的 sourceRecord为空,或者为单例(独占一个 Task);

    • 待启动的 Activity设置了 SingleTask SingleInstance

  • 调用 findTaskLocked()findActivityLocked()mHistory中得到 ActivityRecord类型的 taskTop对象;

  • 调用 topRunningNonDelayedActivityLocked()判断是否处于栈顶,决定是否创建新的 Activity

  • ActivityRecord设置 TaskRecord

  • 调用 ActivityManagerService.grantUriPermissionFromIntentLocked()授权;

  • 调用 stackActivityLocked()完成启动:

    1. 如果不是新 Task,则从 mHistory中找到对应的 ActivityRecord位置;否则,将其添加到 mHistory末尾;

    2. 设置 ActivityRecordinHistorytrue,表示已经存在与 mHistory中;

    3. 判断是否显示 Activity切换动画,需要与 WindowManagerService交互;

    4. 调用 resumeTopActivityLocked()

ActivityStack::resumeTopActivityLocked():

  • 调用 topRunningActivityLocked()mHistory中找到第一个需要启动的 ActivityRecord,如果没有则启动 Home 页面;

  • 将该 ActivityRecordmStoppingActivitiesmGoingToSleepActivitiesmWaitingVisibleActivities中移除;

  • 如果当前正在 pause 一个 Activity,需要先等待 pause 完毕,然后系统重新调用 resumeTopActivityLocked()

  • mResumedActivity指向上次启动的 Activity,即当前显示的 Activity;如果它不为空,调用 startPausingLocked()中止,并返回;

  • 如果传入的 prev页面不为空,则需要通知 WindowManagerService进行与页面切换相关的工作(停止绘制等);

  • 如果该 ActivityRecord对应的进程已存在,则只需要重启该 Activity

  • 如果不存在,通知 WindowManagerService显示启动页面,并调用 startSpecificActivityLocked():

    1. 调用 ActivityManagerService.getProcessRecordLocked()根据进程名和uid查找进程;

    2. 设置启动时间等信息;

    3. 如果该进程存在,并已经向 ActivityManagerService注册,调用 realStartActivityLocked()启动目标 Activity

    4. 如果该进程不存在,调用 ActivityManagerService.satrtProcessLocked()启动进程;

ActivityManagerService::startProcessLocked():

  • 处理 FLAG_FROM_BACKGROUND标志和 BadProcess

    1. 一个进程如果连续崩溃超过两次, ActivityManagerService会将其 ProcessRecord加入 mBadProcesses

    2. 由于进程崩溃会弹框,所以一般禁止启动处于后台的 BadProcess;但如果是用户触发的(比如点击 button 跳到后台页面),则会把该进程从 mBadProcesses移除,给它“重新做人”的机会;

  • 创建 ProcessRecord对象,并保存到 mProcessNames

  • mProcessesOnHold移除该 ProcessRecord,它用于保存在系统还未准备好就发送启动请求的 ProcessRecord

  • 更新 CPU 信息,从 PackageManagerService查询该进程的 gid;

  • 调用 Process.start(),让 Zygote 派生子进程,该子进程执行 ActivityThread.main():

    1. 调用 Process.setArgV0()设置进程名为 pre-initialized

    2. 创建 ActivityThread对象;

    3. 调用 ActivityThread.attach(false)处理应用进程:

      1. 设置在 DropBoxManagerService日志系统中看到的进程名为 pre-initialized

      2. 调用 RuntimeInit.setApplicationObject(mAppThread.asBinder())

      3. 调用 ActivityManagerService.attachApplicationLocked(mAppThread)

  • 执行电量统计;

  • 如果该进程为 persistent,通知 Watchdog

  • 以 pid 为 key,将该进程的 ProcessRecord保存到 mPidsSelfLocked

  • 发送 PROC_START_TIMEOUT_MSG消息,如果新进程 10s 没有和 ActivityManagerService交互,则认为新进程启动失败;

ActivityManagerService::attachApplicationLocked():

  • 根据 pid查找对应的 ProcessRecord;如果为空(未向 ActivityManagerService注册):

    1. 如果 pid大于 0 且不是 system_server进程,调用 Process.killProcessQuiet()杀掉该进程;

    2. 否则调用 IApplicationThread.sheduleExit()退出;

  • 如果该 ProcessRecord.thread对象不为空,表示该进程为旧的未被杀死的进程,系统不会重用,而是调用 handleAppDiedLocked()处理;

  • 创建应用死亡讣告对象 AppDeathRecipient,并调用 thread.asBinder().linkToDeath()

  • 设置该进程的调度优先级以及 oom_adj 相关变量;

  • 通过 PackageManagerService查询运行在该进程中的 ContentProvider对象;

  • 对相关 Package 进行 Dex 优化;

  • 调用 ApplicationThread.bindApplication()

    1. 调用 ServiceManager.initServiceCache()保存 ActivityManagerService传递过来的 Service信息;

    2. 调用 setCoreSettings()向主线程消息队列添加 SET_CORE_SETTINGS消息;

    3. 创建 AppBindData对象,用于保存 processNameappInfo等参数信息;

    4. 初始化性能统计对象 Profiler

    5. 调用 Process.setArgV0()DdmHandleAppName.setAppname()设置正式进程名;

    6. 对于 persistent 进程,在低内存设备上,调用 HardwareRenderer.disable(false)禁用硬件加速;

    7. 初始化 AsyncTask的线程池;

    8. 设置时区、语言、资源、兼容模式;

    9. 根据传过来的 ApplicationInfo创建一个对应的 LoadedApk对象;

    10. StrictMode 和 DebugMode 相关处理;

    11. 设置 HTTP 代理信息;

    12. 如果 Package 声明了 FLAG_LARGE_HEAP,调用 VMRuntime.getRuntime().clearGrowthLimit()清除内存限制;

    13. 根据 LoadedApk对象,并利用反射,生成 Manifest 文件中声明的 Application对象;用 mInitialApplication保存该进程中创建的第一个 Application

    14. 调用 installContentProviders()安装本 Package 下的 ContentProvider

    15. 调用 mInstrumentation.callApplicationOnCreate()执行 Application对象的 onCreate()方法;

  • 调用 updateLruProcessLocked()

  • 调用 ActivityStack.topRunningActivitylLocked()获取 ActivityStack中的第一个需要运行的 ActivityRecord

  • 根据 processNameuid确定该 ActivityRecord和目标进程有关,否则调用 ActivityStack.ensureActivitiesVisibleLocked()处理;

  • 调用 ActivityStack.realStartActivityLocked()启动该 ActivityRecord

  • 对于 mPendingServices中处于 pending 状态的 ServiceRecord

    1. 如果根据 processNameuid判断和目标进程无关,则不作处理;

    2. 否则调用 realStartService()启动该 ServiceRecord

  • 如果上面几个组件初始化有错误,调用 handleAppDiedLocked()处理;

  • 调用 updateOomAdjLocked()根据该进程中的组建情况调节 oom_adj 值(组件越多越不易被杀死回收);

ActivityStack::realStartActivityLocked():

  • 调用 ActivityManagerService.updateConfigurationLocked()处理 Config 变化;

  • ActivityRecord加入到 ProcessRecordactivities中保存;

  • 调用 ActivityManagerService.updateLruProcessLocked()更新进程优先级;

  • 调用 ProcessRecord.threadActivityThread类型)的 scheduleLaunchActivity()通知应用的主进程启动 Activity:

    1. 调用 performLaunchActivity():

      1. 通过反射机制创建目标 Activity对象;

      2. 调用 ActivityonCreate() onStart()方法;

    2. 调用 handleResumeActivity()

      1. 调用 performResumeActivity()执行 ActivityonResume()方法;

      2. 将上面完成 onResume()Activity保存到 mNewActivities中;

      3. 调用 Looper.myQueue().addIdleHandler()向消息队列添加一个 Idler对象:

        • MessageQueue对 Idle 消息会最后处理;

        • 这里的 Idler对象内部会调用 ActivityManagerService.activityIdle()

    3. 如果启动失败,调用 ActivityManagerService.finishActivity()

  • 设置 mResumedActivity(最近启动的 Activity) 为当前 ActivityRecord

  • 调用 ActivityManagerService.addRecentTaskLocked()将该 ActivityRecord.task加入到最近任务列表;

  • 调用 completeResumeLocked(),发送消息处理上面的 Idler对象,进而执行 ActivityManagerService.activityIdle():

    1. 释放 WakeLock类型的 mLaunchingActivity,它能防止启动 Activity过程中掉电;

    2. 调用 processStoppingActivitiesLocked()得到因本次启动而被 pause 的 Activity

    3. 如果他们处于 finishing 状态,则调用其 onDestroy()

    4. 否则调用其 onStop()

    5. 如果当前处于启动过程中(启动 Home 页面时),发送 ACTION_BOOT_COMPLETED广播;

  • 调用 checkReadyForSleepLocked()检查调用过程中是否有休眠请求(比如用户按了电源键);

  • 调用 ActivityManagerService.startSetupActivityLocked()启动系统设置向导页面(初次使用时);

ActivityStack::startPausingLocked():

  • 处理页面跳转前, ActivityManagerService会首先调用本方法处理当前活动的页面;

  • 保存当前显示的 Activity,并设置其 state ActivityState.PAUSING

  • 调用当前 Activity所在进程的 schedulePauseActivity(),内部调用 handlePauseActivity():

    1. 调用 ActivityonUserLeaving()onPause()

    2. 设置 ActivitystateActivityState.PAUSED

    3. 将暂停的 Activity加入到 mStoppingActivities中;

    4. mStoppingActivities数目大于 3,调用 scheduleIdleLocked(),进而执行 ActivityManagerService.activityIdle()

    5. 调用 resumeTopActivityLocked()启动目标 Activity

  • 调用 WakeLock类型变量 mLaunchingActivity.acquire()

  • 调用当前 ActivitypauseKeyDispatchingLocked()停止事件分发;

BroadcastReceiver 与 PendingResult 和 IIntentReceiver:

  • PendingResult是 Android 2.3 新增的 BroadcastReceiver内部类,用于异步处理广播消息:

    1. 先调用 BroadcastReceiver.goAsync()得到一个 PendingResult对象;

    2. PendingResult对象放到工作线程处理,使得 onReceive()不会阻塞;

    3. 工作线程执行完后,需要调用 PendingResult.finish()来完成整个广播的处理流程;

  • IIntentReceiver用于广播相关的跨进程 Binder 通信;

ContextImpl::registerReceiverInternal():

  • 如果没有传入 Handler参数,调用 mMainThread.getHandler()获取主线程 Handler

  • 如果传入的 mPackageInfo参数非空,调用 mPackageInfo.getReceiverDispatcher()得到 IIntentReceiver对象;

  • 否则创建一个 LoadedApk.ReceiverDispatcher对象;

  • 调用 ActivityManagerService.registerReceiver()方法:

    1. 调用 getRecordForAppLocked()

    2 .检查 callerPackage是否在 callearApp.pkgList中,否则抛出 SecurityException

    1. 查询符合 IntentFilter条件的 Sticky Intent,并返回第一个;

    2. 通过 mRegisteredReceiversIIntentReceiver得到 ReceiverList对象:

      • 一个 BroadcastReceiver可设置多个过滤条件,也可以多次调用 registerReceiver()使用不同条件,所以采用 ReceiverList保存这种一对多关系;它继承自 ArrayList<BroadcastFilter>

      • ReceiverListreceiver成员指向 IIntnetReceiver对象;

      • ActivityManagerServicemRegisteredReceivers保存所有 IIntentReceiver和它对应的 ReceiverList

    3. 如果是首次调用,上面返回的 ReceiverList对象为空,则创建该类型对象;

    4. 调用 IIntentReceiver.asBinder().linkToDeath()监听广播接收者所在进程的死亡事件;

    5. 将上面的 ReceiverList对象保存到 mRegisteredReceivers中;

    6. 创建 IntentFilter的子类 BroadcastFilter对象,并调用 mReceiverResolver.addFilter()

ContextImpl::sendBroadcast():

内部调用 ActivityManagerService.broadcastIntentLocked():

  1. 如果是 Sticky 广播:

    1. 检查发送进程是否有 BROADCAST_STICKY权限;

    2. 发送 Sticky 广播不能携带权限信息,也不能指定特定的接收对象;

    3. 将该 Intent保存到 mStickyBrodcasts中,如果存在则替换;

  2. 定义变量 receivers(用于保存所有广播接收者)和 registeredReceivers(用于保存动态注册的接收者);

  3. 如果通过 IntentComponent指定了接收者,则从 PackageManagerService查询接收者其信息;

  4. 通过 PackageManagerService查询 Manifest 文件中声明的(静态)接收者,保存到 receivers

  5. 通过 ActivityManagerServicemReceiverResolver对象查询所有动态注册的接收者,保存到 registeredReceivers

  6. 处理动态注册的接收者:

    1. 如果不是 Ordered 广播,直接创建 BroadcastRecord

    2. 如果没有被替换,保存到 mParcelledBroadcasts

    3. 调用 ActivityManagerService.scheduleBroadcastsLocked()发送广播;

  7. 将动态注册者 registeredReceivers的成员合并到 receivers中;

  8. 创建 BroadcastRecord对象,如果没有替换,保存到 mOrderedBroadcasts(不区分是否 Ordered )中,并调用 ActivityManagerService.scheduleBroadcastsLocked()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值