开机向导启动流程

首先来看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配置文件:

android:theme="@android:style/Theme.NoDisplay"

android:excludeFromRecents="true">

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

看一下Provision中DefaultActivity.java源码:

public class DefaultActivity extends Activity {

@Override

protected 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 View的加载过程

    2019独角兽企业重金招聘Python工程师标准>>> 大家都知道Android中加载view是从Activity的onCreate方法调用setContentView开始的,那么V ...

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

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

  3. android开机字库加载过程,小米手机字库维修更换和EMMC字库编程烧写方法教程

    今天又小伙伴问一个问题怎么更换EMMC字库编程烧写? 这里找到了相关内容: 1.手机出现了正常开机但是过几秒就自动关机了. 2.机器拆去后盖的图,为保护个人隐私,关键部位已经马赛克处理了. 3.拆掉中 ...

  4. 【Android】资源加载过程

  5. 设备树语法,加载过程和与驱动的关系

    文章目录 一.设备树语法 1.1 简介 1.2 基本数据格式 1.3 一个例子 1.3.1 根节点 2.3.2 CPU 1.3.3 节点名称 1.3.4 设备 1.3.5 status 1.3.6 编 ...

  6. Java--web.xml加载过程;文件标签详解

    一.web.xml加载过程 我们在启动Javaweb项目时,首先需要启动一个容器(如Tomcat,JBoss) WEB加载web.xml过程如下: 1.在启动Web项目时,容器(如Tomcat,JBo ...

  7. Android开机向导启动流程分析

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

  8. Android 开机自动加载新wifi模块驱动

    在android ROM 开发中经常会遇到产品更换wifi模块的情况,一般常见的wifi驱动android内核中自带都有,无需过多调试,要是碰上内核中没有的就需要根据厂商提供的驱动进行移植. wifi ...

  9. Window7系统的完整开机加载过程的原理和机制

    1.开启电源 计算机系统将进行加电自检(POST).如果通过,之后BIOS会读取主引导记录(MBR)--被标记为启动设备的硬盘的首扇区,并传送被Windows 7建立的控制编码给MBR.这时,Wind ...

最新文章

  1. Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.解决方案
  2. CSDN 开学见面礼!限时免费申请,手慢无!
  3. 专题 19 Makefile的使用
  4. nginx index.php 端口,nginx-如果index.php不在nginx文件夹中,则禁止使用php fpm
  5. 第三十三讲:tapestry表单组件详解之Label
  6. c# winform TreeView与ListView的项互相拖动的应用[转载]
  7. jQuery 根据值或者文本选中select
  8. 你真的会玩SQL吗?玩爆你的数据报表之存储过程编写(下)
  9. windows 内部预览版与迅雷极速版不配合
  10. 去除QQ打/之后会出现的表情
  11. 分享一款在线less转css的神器
  12. 【2020年高被引学者】 韩家炜 伊利诺伊大学香槟分校
  13. 计算机网络教程 azw3,Windows 10从入门到精通(pdf+epub+mobi+txt+azw3)
  14. 柏拉图式爱情 (精神爱情)
  15. 统计push点击次数的shell脚本最初版本1
  16. Huffman文件压缩之文件夹压缩
  17. 提高项目10-编制三角函数表
  18. iOS MultipeerConnectivity
  19. android 文档生成工具,word文档制作生成
  20. 微信公众号及CSDN文章爬取

热门文章

  1. jpa级联添加_请教一个JPA多对多级联保存的问题
  2. 【MAPBOX基础功能】19、mapbox修改鼠标在地图上的样式
  3. Python实现GIF动图以及视频卡通化,两脚踢碎次元壁 | 机器学习
  4. 【实用工具】RD Clinet使用教程之ipad连接windows
  5. 【情报百科】如何利用光影定位美国军事基地?
  6. docker 网络相关与坑
  7. setwd的cannot change working directory处理
  8. 如何写一个自动抢微信红包的程序
  9. 路由桥接 新增路由 扩大wify 一个网线两个wify
  10. dumple什么意思_计算机术语dump是什么意思?