Android开机向导启动流程

首先来看Android启动流程:
1、Bootloader(系统启动加载器,将Linux加载到RAM);
2、Kernel
3、init进程
4、Zygote(Zygote进程是整个android系统的根进程,fork出System server进程);
5、system_server(Android系统的核心进程,负责启动各种系统服务);
6、System Services(由system_server调用startBootstrapServices()、startCoreServices()、startOtherServices()三个方法启动各种服务,其中重要的服务启动顺序如下:
        ActivityManagerService
        PowerManagerService
        PackageManagerService
        WindowManagerService
        StorageManagerService);
接下来就是开机向导的启动过程。

一、在SystemServer类的startOtherServices()方法中,当启动了所有需要的服务后,会调用ActivityManagerService类的systemReady()方法,代码如下:

private void startOtherServices() {final Context context = mSystemContext;VibratorService vibrator = null;...       // We now tell the activity manager it is okay to run third party// code.  It will call back into us once it has gotten to the state// where third party code can really run (but before it has actually// started launching the initial applications), for us to complete our// initialization.mActivityManagerService.systemReady(() -> {Slog.i(TAG, "Making services ready");traceBeginAndSlog("StartActivityManagerReadyPhase");mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);traceEnd();traceBeginAndSlog("StartObservingNativeCrashes");...
}

二、ActivityManagerService类的systemReady()方法会调用startHomeActivityLocked()方法,开始执行启动HomeActivity的操作。

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {...startHomeActivityLocked(currentUserId, "systemReady");...
}

我们来看startHomeActivityLocked()方法:

 Intent getHomeIntent() {Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);intent.setComponent(mTopComponent);intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {intent.addCategory(Intent.CATEGORY_HOME);}return intent;}boolean startHomeActivityLocked(int userId, String reason) {if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL&& mTopAction == null) {// We are running in factory test mode, but unable to find// the factory test app, so just sit around displaying the// error message and don't try to start anything.return false;}Intent intent = getHomeIntent();ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);if (aInfo != null) {intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));// Don't do this if the home app is currently being// instrumented.aInfo = new ActivityInfo(aInfo);aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);ProcessRecord app = getProcessRecordLocked(aInfo.processName,aInfo.applicationInfo.uid, true);if (app == null || app.instr == null) {intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);// For ANR debugging to verify if the user activity is the one that actually// launched.final String myReason = reason + ":" + userId + ":" + resolvedUserId;mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);}} else {Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());}return true;}

首先调用getHomeIntent()方法,该方法为Intent对象添加了Intent.CATEGORY_HOME常量,之后调用了ActivityStarter类的startHomeActivityLocked()方法,然后就是Activity的启动流程啦,关于Activity的启动流程请看我上一篇博客Activity启动流程分析。最后响应android.intent.category.HOME属性的应用就被启动了。

三、通过上面的流程,我们知道,Android通过ActivityManagerService类中的startHomeActivityLocked方法,发送一个带有android.intent.category.HOME的intent来启动响应该属性的应用。一般Launcher的AndroidManifest配置文件中都会有该属性,所以系统的Launcher就是这样被启动了。

再来看Android中的Provision应用(/packages/apps/provision),Provision其实就是类似刚出厂时或者恢复出厂设置之后,一步一步引导用户完成各种设置的Setup Wizard程序,就是我们所说的开机向导,它的主要作用是:引导用户进行一些基本设置。在原生的Android系统中,Provision只有一个空白的Activity,我们可以根据需求自己定制开机向导。
来看看Provision应用的AndroidManifest配置文件:

 <application><activity android:name="DefaultActivity"android:theme="@android:style/Theme.NoDisplay"android:excludeFromRecents="true"><intent-filter android:priority="3"><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.HOME" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.SETUP_WIZARD" /></intent-filter></activity></application>

可以看到Provision也会响应android.intent.category.HOME属性,并且它的android:priority属性值为3,整数值越大,优先级越高,可见它的优先级要比一般的Launcher高,所以在AMS的startHomeActivityLocked()方法启动HomeLauncher的时候会先启动Provision应用,即开机向导,然后才启动Launcher。

看一下Provision中DefaultActivity.java源码:

public class DefaultActivity extends Activity {@Overrideprotected void onCreate(Bundle icicle) {super.onCreate(icicle);// Add a persistent setting to allow other apps to know the device has been provisioned.Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);Settings.Secure.putInt(getContentResolver(), Settings.Secure.TV_USER_SETUP_COMPLETE, 1);// remove this activity from the package manager.PackageManager pm = getPackageManager();ComponentName name = new ComponentName(this, DefaultActivity.class);pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);// terminate the activity.finish();}
}

首先在Global表中将DEVICE_PROVISIONED属性设置为1(这个标志很重要,因为很多地方都会检查该标志是否被置为1来决定是否要走正常的流程,比如锁屏、各种Service等),在Secure表中将USER_SETUP_COMPETE属性和TV_USER_SETUP_COMPLETE属性设置为1。然后通过PackageManager对象的setComponentEnabledSetting()方法将自己设置成不可用状态,所以开机向导只会执行一次。最后关闭Activity。

如果开机向导没有执行,DEVICE_PROVISIONED属性没有被设置为1,则会导致很多功能不可用,比如无法锁屏、按home键没有反应等。

Android开机向导启动流程分析相关推荐

  1. android 开机向导加载过程,开机向导启动流程分析

    开机向导启动流程 首先来看Android启动流程: 1.Bootloader(系统启动加载器,将Linux加载到RAM): 2.Kernel 3.init进程 4.Zygote(Zygote进程是整个 ...

  2. c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...

    在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析​zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...

  3. Cocos2d-x3.3RC0的Android编译Activity启动流程分析

    http://www.itnose.net/detail/6142692.html 本文将从引擎源码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,下面是详细分析 ...

  4. android 开机向导加载过程,Android开机向导构建流程

    前言 在设备首次开机的时候我们往往会给与用户一些操作提示,比如如何对焦.遥控器配对等,这个时候就需要一个界面在Launcher启动之前呈现给用户,这个界面就是所谓的开机向导,本质上开机向导就是一个普通 ...

  5. Android M应用启动流程分析

    更新: 2016-10-29:更新handleBindApplication部分. 我这个版本的原则是,有话则长,无话则短. 以下分析基于6.0.1_r10版本. 先看一张大图: 1. 桌面的onCl ...

  6. Android Activity的启动流程分析:以Launcher启动一个Activity为例,分析应用进程的创建、Activity的启动,以及他们和AMS之间的交互

    文章目录 一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity: Step 1. Laun ...

  7. Android 开机动画启动、播放、退出流程(android 10)

    Android 开机动画启动流程 (android 10) 1 开机动画启动流程 我们先来看一下开机动画是如何启动,并开始播放的. 通过系统启动流程分析可以得知,在系统内核启动后,会启动第一个init ...

  8. Android12 应用启动流程分析

    最近因为一些业务上的需求,需要梳理 Android 应用的启动链路,从中寻找一些稳定的锚点来实现一些特殊的功能.本文即为对应用端启动全过程的一次代码分析记录. 注: 本文所分析的代码基于 AOSP a ...

  9. Android系统开机到Launcher启动流程分析

    本文基于Android10.0的源码. 由于google团队在对framework层代码进行大量重构,所以代码变动还是挺大的. 常见基础问题: SystemServer系统服务进程是如何创建的?Lau ...

最新文章

  1. 基本表改变视图不改变为什么_中国白酒包装是真的很丑吗,为什么不改变包装?...
  2. 内核中的kmalloc函数详解
  3. 云通信产品运营带你玩转号码隐私保护
  4. 降为千元机!小米6X 6+64G版到手价999元
  5. 一起来学习BERT常见的几个变体
  6. 集中火力 专项击破|数据分析可视化广深线下培训火热来袭
  7. 工控领域组态软件开发感触
  8. 【Web技术】969- 如何实现高性能的在线 PDF 预览
  9. 浙江开票系统服务器窗口,浙江增值税发票综合服务平台常见问题解答
  10. 系统测试包含的全部内容(建议收藏)
  11. MySql + JDBC 数据库基础的操作(防止sql注入的方法)
  12. sqlserver数据库错误码
  13. Unity3D教程:简单触发器实现自动开关门
  14. gentoo php,Gentoo 下安装 PHP 扩展
  15. UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xae in position 16: illegal multibyte sequence
  16. OpenCV4-C++读图、显示图
  17. 采药(洛谷P1048)
  18. 2017年:电子书阅读
  19. iOS-通过Message框架开发一个Sticker Pack(无需代码)(第一篇)
  20. 计算机科学与技术和电子信息类哪个好,电子信息类七个专业哪个最好

热门文章

  1. 2012年4月23日
  2. 在查询分析器里执行数据库的备份和还原操作
  3. 生态创客Android应用
  4. postma公共变量的设置及使用
  5. 第一周 平面点的对称点
  6. 单片机汇编伪指令DATA和EQU的区别
  7. c语言开发套路-怎样快速调用别人的一套接口 api模型的抽象
  8. 时无英雄,使竖子成名!
  9. 第一次亲密接触读后感(转)
  10. 第三章程序的机器级表示