launcher是设备开机后的第一个app,作用是用于显示和管理设备的其他app。
在AndroidManifest.xml中添加如下内容就可以将app设置为launcher
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
1.什么是PackageManager?
通俗一点来说PackageManager是用于获取Android系统中应用程序的信息,查询Application相关信息(application,activity,receiver,service,provider及相应属性等)、查询已安装应用、增加或删除permission、清除用户数据、缓存,代码段等。
可以调用PackageManager的queryIntentActivities()方法来获取一个关于App信息(ResolveInfo)的集合,这个ResolveInfo对象中就包含了应用程序的程序名、包名、入口类名等信息。
//获取packageManage对象
PackageManager packageManager = this.getPackageManager();
//设置<intent-filter>满足的条件
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_DEFAULT);
//通过queryIntentActivities获取ResolveInfo对象
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
//调用系统排序,根据name排序;排序很重要,否则只能显示系统应用,不能显示第三方应用
Collections.sort(resolveInfos,new ResolveInfo.DisplayNameComparator(packageManager));
for (ResolveInfo resolveInfo : resolveInfos) {
String appName = resolveInfo.loadLabel(packageManager).toString();// 获取应用名称
String packageName = resolveInfo.activityInfo.packageName;// 包名
String className = resolveInfo.activityInfo.name;// 入口类名
System.out.println("程序名:" + appName + " 包名:" + packageName
+ " 入口类名:" + className);
}
Launcher:继承Activity,是桌面的主界面,因此可知,桌面其实就是一个activity,只是和平常的应用不同,他用来显示图标、Widget和文件夹等;
LauncherModel:继承BroadcastReceiver,由此可知他是一个广播接收器,用来接收广播,另外,LauncherModel还主要加载数据;
LauncherProvider:继承ContentProvider,主要是处理数据库操作;
LauncherAppState:单例模式的全局管理类,主要是初始化一些对象,注册广播等.
Compat:兼容包,带有这个后缀的都是做兼容处理的类.
2. Launcher启动流程
Launcher启动入口在哪儿?
ActivityManagerService的systemReady函数就是启动Launcher的入口。SystemServer系统服务进程是如何创建的?Launcher进程如何被创建的?
是由Zygote进程fork而来Android应用进程的的入口类?
ActivityThread系统如何识别Launcher应用?
android.intent.category.HOME为什么Activity必须在清单文件中注册?
ActivityStarter会做各种启动前检查。
//1.从System.main开始getHomeIntent();
Intent.CATEGORY_HOME
一、Android系统架构及开机流程
Android系统架构
系统启动架构图
首先,关于Android手机开机的过程,Loader层:
Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设代码开始执行,然后加载引导程序到RAM;
Boot Loader:这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数,拉起Android OS。图解: Android系统启动过程由上图从下往上的一个过程是由Boot Loader引导开机,然后依次进入 -> Linux Kernel -> Native -> Framework -> App,接来下简要说说每个过程:
Linux内核层:
Android平台的基础是Linux内核,比如ART虚拟机最终调用底层Linux内核来执行功能。Linux内核的安全机制为Android提供相应的保障,也允许设备制造商为内核开发硬件驱动程序。
启动Kernel的swapper进程(pid=0):该进程又称为idle进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作;
启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖。硬件抽象层 (HAL):
硬件抽象层 (HAL) 提供标准接口,HAL包含多个库模块,其中每个模块都为特定类型的硬件组件实现一组接口,比如WIFI/蓝牙模块,当框架API请求访问设备硬件时,Android系统将为该硬件加载相应的库模块。
系统运行库层:
每个应用都在其自己的进程中运行,都有自己的虚拟机实例。ART通过执行DEX文件可在设备运行多个虚拟机,DEX文件是一种专为Android设计的字节码格式文件,经过优化,使用内存很少。ART主要功能包括:预先(AOT)和即时(JIT)编译,优化的垃圾回收(GC),以及调试相关的支持。
这里的Native系统库主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖。
Framework层:
Zygote进程,是由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:
加载ZygoteInit类,注册Zygote Socket服务端套接字
加载虚拟机
提前加载类preloadClasses
提前加载资源preloadResouces
SystemServer系统服务进程,是由Zygote进程fork而来,System Server是Zygote孵化的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务。
Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service等服务。
Application层:
Zygote进程孵化出的第一个App进程是Launcher,这是用户看到的桌面App;
Zygote进程还会创建Browser,Phone,Email等App进程,每个App至少运行在一个进程上。
所有的App进程都是由Zygote进程fork生成的。
二、Android系统中极其重要的进程:
init进程, Zygote进程, SystemServer进程, ServiceManager进程。
2.1.init进程
Init进程是Android启动的第一个进程,进程号为1(pid=1),是Android 的系统启动的核心进程,主要用来创建Zygote、属性服务等。 init.cpp 中的main 函数,是init进程的入口函数,源码主要存在\system\core\init目录下。
重点:它是Linux系统中用户空间的第一个进程,由于Android是基于Linux内核的,所以init也是Android系统中用户空间的第一个进程。
init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程(守护进程一般以d结尾);
init提供property service(属性服务)来管理Android系统的属性。
init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务
init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程(即虚拟机进程),Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。