最近在弄开机向导,网上查了查,基本都是参照系统的​​​​​​Provision应用来做的,而且还要将apk打包到系统目录下的pri-app目录下,打包到其他目录下不行,参照着做是没问题,但是好奇为什么要这么做?调用流程是怎样?这就是接下来要来探究的。

launcher启动

以如下模拟器为例来看Google首次开机涉及到哪些launcher

开机时过滤日志ActivityTaskManager

2023-01-29 16:44:03.285 1993-1993/system_process I/ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.settings/.CryptKeeper} from uid 0
2023-01-29 16:44:03.289 1993-1993/system_process I/ActivityTaskManager: Loaded persisted task ids for user 0
2023-01-29 16:44:04.089 1993-2096/system_process I/ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.setupwizard/.SetupWizardActivity} from uid 0
2023-01-29 16:44:05.129 1993-2347/system_process I/ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.settings/.FallbackHome} from uid 0
2023-01-29 16:44:06.212 1993-2032/system_process I/ActivityTaskManager: Displayed com.android.settings/.FallbackHome: +1s80ms
2023-01-29 16:44:14.244 1993-2610/system_process I/ActivityTaskManager: Config changes=3 {1.0 310mcc260mnc [en_US] ldltr sw392dp w392dp h757dp 440dpi nrml long port finger qwerty/v/v dpad/v winConfig={ mBounds=Rect(0, 0 - 1080, 2280) mAppBounds=Rect(0, 0 - 1080, 2148) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} s.6}
2023-01-29 16:44:14.264 1993-2610/system_process I/ActivityTaskManager: Override config changes=3 {1.0 310mcc260mnc [en_US] ldltr sw392dp w392dp h757dp 440dpi nrml long port finger qwerty/v/v dpad/v winConfig={ mBounds=Rect(0, 0 - 1080, 2280) mAppBounds=Rect(0, 0 - 1080, 2148) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} s.6} for displayId=0
2023-01-29 16:44:16.159 1993-2024/system_process I/ActivityTaskManager: Loading recents for user 0 into memory.
2023-01-29 16:44:16.436 1993-3016/system_process I/ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.sdksetup/.DefaultActivity} from uid 0
2023-01-29 16:44:19.084 1993-2047/system_process I/ActivityTaskManager:   Force finishing activity ActivityRecord{cb6abf3 u0 com.google.android.sdksetup/.DefaultActivity t4}
2023-01-29 16:44:19.086 1993-2047/system_process I/ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.apps.nexuslauncher/.NexusLauncherActivity} from uid 0
2023-01-29 16:44:19.234 1993-2028/system_process W/system_server: Long monitor contention with owner PackageManager (2047) at void com.android.server.wm.ActivityTaskManagerService$LocalService.cleanupDisabledPackageComponents(java.lang.String, java.util.Set, int, boolean)(ActivityTaskManagerService.java:6820) waiters=0 in void com.android.server.wm.InputMonitor$1.run() for 150ms
2023-01-29 16:44:26.653 1993-2032/system_process I/ActivityTaskManager: Displayed com.google.android.apps.nexuslauncher/.NexusLauncherActivity: +5s191ms

涉及到应用包括:

1、com.android.settings/.CryptKeeper

2、com.google.android.setupwizard/.SetupWizardActivity

3、com.android.settings/.FallbackHome

4、com.google.android.sdksetup/.DefaultActivity

5、com.google.android.apps.nexuslauncher/.NexusLauncherActivity

开机涉及到这么多页面,但我们实际能感觉到的就只有FallbackHome和NexusLauncherActivity两个页面,NexusLauncherActivity就是我们最终显示的launcher了,FallbackHome则是开机动画完成后出现的一个加载动画(Pixs is Starting ...)。

再说launcher启动前,先来看下验证的几个方法:

    fun testApi() {val homeIntent = Intent(Intent.ACTION_MAIN)homeIntent.addCategory(Intent.CATEGORY_HOME)val resolvedType = homeIntent.resolveTypeIfNeeded(contentResolver)val queryIntentActivities = AppGlobals.getPackageManager().queryIntentActivities(homeIntent, resolvedType,PackageManager.GET_SHARED_LIBRARY_FILES, 0)for (parcelable in queryIntentActivities.list) {val toString = (parcelable as ResolveInfo).toString()Log.d(ZZQ_TAG, "queryIntentActivities: "+toString)}val resolveIntent = AppGlobals.getPackageManager().resolveIntent(homeIntent, resolvedType,PackageManager.GET_SHARED_LIBRARY_FILES, 0)Log.d(ZZQ_TAG, "resolveIntent: "+resolveIntent.toString())}

queryIntentActivities()查询到的就是当前所有匹配到的activity信息,而resolveIntent()就是获取当前优先级最高的launcher,用这个方法测试时,需要注意这个应用要是系统应用,有系统签名和menifest中需要加android:sharedUserId="android.uid.system",否则拿到的就不全,

对于launcher启动属性的页面,当页面起来后,调用它的finish()方法,就会重新去启动优先级高的launcher(调用Activity的pause()方法后,系统会重新执行启动launcher),可能会有疑问,重新启动不还是刚finish()点的launcher么,正常来说是的,但是如果调用了如下方法:

        val defaultName = ComponentName("com.android.provision", "com.android.provision.DefaultActivity")pm.setComponentEnabledSetting(defaultName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP)

那么在PackageManager中就会去掉这个Activity的信息,自然重新查找launcher就不是原来的launcher了,按照这个逻辑,除了首次开机会启动所有的launcher,其他时候开机就只剩NexusLauncherActivity了,但是每次打开模拟器时,都会有FallbackHome的加载动画,那就说明FallbackHome并没有从包管理中去掉,那是怎么跳过FallbackHome启动后面的Launcher的呢?那这就要看android:directBootAware="true"了,这个属性的意思是当设备未解锁时是否允许被启动,true表示可以启动,false表示不可以启动,FallbackHome就配置了这个属性,并且FallbackHome是在监听到解锁后finish()掉的,接下来看下这几个页面在menifest的配置:

1、com.android.settings/.CryptKeeper

    <applicationandroid:directBootAware="true"><activityandroid:theme="@ref/0x7f13027a"android:name="com.android.settings.CryptKeeper"android:process=":CryptKeeper"android:excludeFromRecents="true"android:launchMode="1"android:screenOrientation="5"android:configChanges="0x233"android:windowSoftInputMode="0x10"android:immersive="true"androidprv:systemUserOnly="true"><intent-filter android:priority="10"><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.HOME" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity></application>

2、com.google.android.setupwizard/.SetupWizardActivity

        <activityandroid:theme="@ref/0x7f1100b0"android:label="@ref/0x7f100028"android:name="com.google.android.setupwizard.SetupWizardActivity"android:excludeFromRecents="true"android:launchMode="2"android:configChanges="0x4b3"android:immersive="true"android:directBootAware="true"><intent-filter android:priority="5"><action android:name="android.intent.action.MAIN" /><action android:name="android.intent.action.DEVICE_INITIALIZATION_WIZARD" /><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>

3、com.android.settings/.FallbackHome

    <applicationandroid:directBootAware="true"><activityandroid:theme="@ref/0x7f130104"android:label="@string/0x32"android:name="com.android.settings.FallbackHome"android:taskAffinity="com.android.settings.FallbackHome"android:excludeFromRecents="true"android:screenOrientation="5"><intent-filter android:priority="-1000"><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.HOME" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity></application>

4、com.google.android.sdksetup/.DefaultActivity

        <activityandroid:name="DefaultActivity"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" /></intent-filter></activity>

5、com.google.android.apps.nexuslauncher/.NexusLauncherActivity

        <activityandroid:theme="@ref/0x7f12000a"android:name="com.google.android.apps.nexuslauncher.NexusLauncherActivity"android:enabled="true"android:taskAffinity="@string/0x35"android:clearTaskOnLaunch="true"android:stateNotNeeded="true"android:launchMode="2"android:screenOrientation="-1"android:configChanges="0xdf3"android:windowSoftInputMode="0x20"android:resumeWhilePausing="true"android:resizeableActivity="true"><intent-filter><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.MONKEY" /><category android:name="android.intent.category.LAUNCHER_APP" /></intent-filter><meta-dataandroid:name="com.android.launcher3.grid.control"android:value="com.google.android.apps.nexuslauncher.grid_control" /></activity>

上面这些就是Pixel 5模拟器所有launcher配置,系统启动选取launcher是通过上面提到的resolveIntent()这个方法解决,感兴趣的可以自己去看看源码,在开机时,系统是没有解锁的,所以只会找到配置了android:directBootAware="true"的Activity,所以这里先找到的是CryptKeeper、SetupWizardActivity、FallbackHome,然后再来看下优先级,CryptKeeper的priority是10、SetupWizardActivity的priority是5、FallbackHome的priority是-1000,优先级高的先执行,CryptKeeper、SetupWizardActivity执行完后通常都是会从包管理中移除,在执行到FallbackHome时,FallbackHome有解锁的监听,解锁完成就直接finish()掉了,但不会从包管理中移除,这也就是每次开机都能看到一个加载的动画,FallbackHome执行完后,再次寻找launcher时,找到是FallbackHome、DefaultActivity、NexusLauncherActivity,同样根据优先级,这时候由于FallbackHome的优先级是-1000,所以是不会执行了,DefaultActivity执行完后会直接从包管理中移除,所以最终显示的就是NexusLauncherActivity了,而在后续的开机中,就只会涉及到FallbackHome和NexusLauncherActivity了,这样开机中涉及到的所有launcher就全了。上面所涉及到的五个Activity,其中SetupWizardActivity、DefaultActivity是开机向导,为什么Pixel 5中会有两个开机向导,这就不是很明白了(个人猜测可能是在设置SetupWizardActivity的过程中,就已经解锁了,而有些设置需要在解锁后设置)。

2、自定义开机向导

明白了开机流程中的原理,再来弄开机向导就很简单。

现在就可以来自定义我们的开机向导了,按照网上大部分教程是参照Provision这个应用,这里就会有个问题,如果开机向导中有设置语言,在首次开机时,FallbackHome的加载动画的文本就只能使用系统默认的语言了,而且还延长了开机时间,所以建议参照SetupWizardActivity来配置,这样有几个好处:

1、可以不将包放到系统目录的pri-app目录下;

2、首次开机可以省略掉FallbackHome加载动画(前提是开机向导设置完成时设备已解锁);

如果有些需求需要系统解锁后在进行设置,那就可以参照网上的Provision了,如果你不想将包打包进pri-app目录下(后续手动安装覆盖不掉),也是有解决方案的,那就是重新设置launcher的优先级,不过这里需要注意下,不再pri-app目录下,设置1到1000是无效的,只能设置0到-1000,这样所有问题都可以解决了。

Android10 开机向导流程相关推荐

  1. Android10开机向导中复用设置中的Wifi界面

    很多时候我们需要定制开机向导,在开机向导界面我们一般会实现联网和设置时间等功能,考虑复用与稳定性问题,我们最好复用设置中的WiFi设置和日期设置.但是设置中的wifi设置界面默认是没有下一步按钮的,这 ...

  2. Android 开机向导(没有优先启动问题)

    1.设置了开机向导的相关属性却没有优先启动 <activity android:name="DefaultActivity"android:excludeFromRecent ...

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

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

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

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

  5. Android10定制Google开机向导

    文章目录 1.简介 2.修改wizard_script.xml 3.编写自己的Activity 3.1 AndroidManifest.xml声明action 3.2 如何退出Activity 4 开 ...

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

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

  7. Android10系统开发实现跳过开机向导、插电源线不休眠等默认配置

    一.前言 在刷机玩机过程中,常常遇到刷机之后烦人的开机引导设置.特别是有强迫症的人,多希望开机之后就跳转到主界面.经过研究了一下,可以通过修改安卓源码中的默认设置跳过开机引导,此外还有很多其他功能,比 ...

  8. RedHat开机启动流程

    RedHat 开机启动流程 : 1. LILO 取得控制权. PC 起动时, 会读取开机磁碟第一条 cylinder 的第一个 sector(此即 MBR), 然後它会试着将读取到的程式码载入记忆体中 ...

  9. (转)CentOS 7系统详细开机启动流程和关机流程

    CentOS 7系统详细开机启动流程和关机流程 原文:http://blog.csdn.net/yuesichiu/article/details/51350654 名称 bootup - 系统启动流 ...

最新文章

  1. 使用Nmap获取目标服务器开放的服务以及操作系统信息
  2. 010_Spring Data JPA一对多关系
  3. ubuntu 安装spark
  4. concurrent: ThreadPoolExecutor 用法
  5. sqlserver导入向导时提示外部表不是预期格式_Excel办公实操,导入本地数据,创建参数查询,就是简单...
  6. fgetcsv()函数
  7. 保证一致性吗_RabbitMQ消息一致性:重要消息,请设置持久化
  8. 从数组中删除最后一项
  9. docker+阿里云镜像容器进行环境的备份与获取
  10. 网工常用网络命令合集✨(建议收藏)
  11. RTEC机器人_广东省中小学电脑机器人活动获奖结果公布
  12. boost | 线程与并发(一)atomic
  13. 胡说八道设计模式—观察者模式
  14. 华为路由器交换机命令汇总-持续更新
  15. 数学表达式基础——1 基本符号与术语
  16. Java技术——Interface与abstract类的区别
  17. 空洞卷积(Atrous/Dilated Convolution)
  18. 那些年啊 那些事 一个程序员的奋斗史 121
  19. 产品:关键词与分类---人人都是产品经理day02
  20. 问题合集 ----- linux下编译工具 make及相关

热门文章

  1. 中业科技机器人价格_中业科技发布年度报告 净利润同比增长69.89%
  2. 二手笔记本 检测流程!
  3. 网络开发套接字以及UDP、TCP协议
  4. 史上最全!统计学常用的数据分析方法大总结
  5. 2019数学建模赛后感悟:一次灵魂与肉体的交织一次参赛终身收益
  6. 如何识别公众号阅读刷量
  7. MagicalRecord
  8. 「Python条件结构」根据输入数量对应的折扣率计算应付金额
  9. JavaScript求最大公约数和最小公倍数
  10. rust编程-rust所有权理解(chapter 4.2 引用实质是借用)