《深入理解 Android》笔记:ActivityManagerService

ActivityManagerService 概述:

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

  • ActivityManagerService 继承自 ActivityManagerNative 类,并实现了Watchdog.Monitor 和 BatteryStatsImpl.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. 创建 BatteryStatsService 和 UsageStatsService ;

      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 对象;

  • 调用 BatteryStatsService 和 UsageStatsService 的 publish() 方法;

  • 调用 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() 查询包名为android 的 ApplicationInfo 对象;

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

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

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

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

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

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

    2. 创建 ProcessRecord 对象:

      1. 初始化 BatteryStatsService 、 ApplicationInfo 、 ProcessName、 IApplicationThread 等成员变量;

      2. 初始化 maxAdj 、 hiddenAdj 、 curRawAdj 、 curAdj 等和进程调度和内存管理相关的变量;

      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_UID 的ProcessRecord ,即 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. 从 ProcessRecord 的 pubProviders 中找到对应的ContentProviderRecord ,如果找到则以 authority 为 key 保存;

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

      4. 调用 updateOomAdjLocked() 调整 oom_adj;

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

  • 调用 UsageStatsService.monitorPackages() ;

ContentProvider:

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

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

  • ContentProvider 的 getIContentProvider() 返回 Transport 对象;

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

ContentProviderRecord:

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

  • ActivityManagerService 的 mProviderByClass 成员和 ProcessRecord的 pubProviders 成员均以 ComponentName 为 key 来保存对应的ContentProviderRecord ;

ProviderClientRecord:

  • ProviderClientRecord 是 ActivityThread 提供的用于保存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:

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

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

  • ActivityStack 的 mHistory 成员是 ArrayList 类型,用于保存系统中所有ActivityRecord ;

  • ActivityStack 没有变量保存所有 TaskRecord ;

ActivityStack::startActivityMayWait():

  • 从 PackageManagerService 查询匹配传入的 Intent 的 ActivityInfo ;

  • 获取 Binder 调用方 uid 和 pid;

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

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

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

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

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

    5. 创建 ActivityRecord 对象;

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

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

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

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

  • 处理启动结果;

ActivityStack::startActivityUncheckedLocked():

  • 判断是否需要创建新的 Task,以下两种情况需要在 Intent 的 flags 附加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. 设置 ActivityRecord 的 inHistory 为 true ,表示已经存在与mHistory 中;

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

    4. 调用 resumeTopActivityLocked() ;

ActivityStack::resumeTopActivityLocked():

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

  • 将该 ActivityRecord 从 mStoppingActivities 、mGoingToSleepActivities 和 mWaitingVisibleActivities 中移除;

  • 如果当前正在 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 对象,用于保存 processName 、 appInfo 等参数信息;

    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 ;

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

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

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

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

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

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

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

ActivityStack::realStartActivityLocked():

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

  • 将 ActivityRecord 加入到 ProcessRecord 的 activities 中保存;

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

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

    1. 调用 performLaunchActivity() :

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

      2. 调用 Activity 的 onCreate() 和 onStart() 方法;

    2. 调用 handleResumeActivity() :

      1. 调用 performResumeActivity() 执行 Activity 的 onResume() 方法;

      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. 调用 Activity 的 onUserLeaving() 和 onPause() ;

    2. 设置 Activity 的 state 为 ActivityState.PAUSED ;

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

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

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

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

  • 调用当前 Activity 的 pauseKeyDispatchingLocked() 停止事件分发;

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. 通过 mRegisteredReceivers 和 IIntentReceiver 得到 ReceiverList对象:

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

      • ReceiverList 的 receiver 成员指向 IIntnetReceiver 对象;

      • ActivityManagerService 用 mRegisteredReceivers 保存所有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. 如果通过 Intent 的 Component 指定了接收者,则从PackageManagerService 查询接收者其信息;

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

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

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

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值