一: 这篇将分析手机从加电那一刻到Home应用启动的过程,如下图简要描述了启动过程
system_server在开启核心服务的时候,其中有一个服务是ActivityManagerService,简称AMS; 主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,在系统进程到ready阶段的时候,AMS将会通过zygote启动Home应用
二:关于1号进程和0好进程进程
init进程是Android用户空间的1号进程,在linux中也存在0号进程;
当内核被加载到内存后,首先就会有完成内核初始化的函数start_kernel()从无到有的创建一个内核线程swap,并设置其PID为0,即进程0;它也叫闲逛进程;进程0执行的是cpu_idle()函数,该函数仅有一条hlt汇编指令,就是在系统闲置时用来降低电力的使用和减少热的产生。同时进程0的PCB叫做init_task,在很多链表中起了表头的作用。
init进程从不终止,用来创建和监控操作系统外层的所有进程的活动。
三:关于init进程
3.1 源码位置
system/core/init目录,其入口函数为system/core/init/init.c的main函数中
3.1 inti.c中main函数主要作用
- 创建基本文件系统目录并挂在文件系统
- 初始化内核Log系统
- 解析并触发inti.c配置文件中的各种action,service和command
- 属性服务的处理
3.2 init.c中main函数中相关方法的解释
mkdir(“/dev”, 0755)
创建文件目录命令,第一个为文件创建位置,第二个参数表示文件组操作权限
Linux 系统中采用三位十进制数表示权限,如0755, 0644.
0755->即用户具有读/写/执行权限,组用户和其它用户具有读写权限;
0644->即用户具有读写权限,组用户和其它用户具有只读权限;
mount(“devpts”,“/dev/pts”,”devpts”,0,NULL)
linux 的理念就是everything is file
挂载是指将一个设备(通常是存储设备)挂接到一个已存在的目录上。 我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的目录上, 然后通过访问这个目录来访问存储设备。
mount用法
四:关于init.rc的简要分析
4.1 该配置文件由Android初始化语言定义;
该配置文件由不同的Section组成,每一个Section都有不同的Action(行动)或者Service(服务),我们可以用On来声明一个Action;用service来声明一个Service;每一个Action或者Service都有若干Command(命令),每一个Command都有若干Trigger(触发条件); 这里的Service都是init进程的子进程,由关键字service,服务名和服务对应的命令的路径,命令的参数和Option(可选项,主要作为服务启动的配置参数)组成,代表在初始化阶段启动的程序
4.2 关于Android初始化语言中的Option中重要参数解读
-critical 核心服务,在一定时间内退出多次,将导致系统重启到revovery mode
-disable 开机时禁止此服务,但可以手动启动它
4.3 关于如何查看Command是在哪里执行
- 在init_parser.c中,定义了一个keyword_info的宏,在这个文件中有很多KEYWORD的函数,执行Command就是执行这些函数
- 如
On early-init
write / .....
start / .....
on定义了一个Action,write和start则是对应的Command,对应执行的函数为do_write和do_start
五:关于在init进程中启动的Service
5.1 在init.c的main函数中,执行到action_for_each_trigger(“boot”….),在触发boot Action的过程中,将要启动的Service与Command关联起来
5.2 init把Service作为一个进程,用Command通过fork的方式启动的,这样所有Service就是init的子进程了;由init启动的Service主要有ueventd,servicemanager,zygote,install,bootanim等,我们称这些Service为守护进程服务
5.3 这里的Service与Android开发中的service组件是否为同一个概念
不是,这里的Service是服务的概念,不同于Android开发过程的service组件;这里的Service多由C++实现;
5.4 属性服务的启动,即内置Action的启动
5.4.1 什么是属性服务
Linux系统启动的时候,由init初始化并开启属性服务;提供了一个系统属性共享内存区,用于存储全局系统设置信息。
属性服务的文件多是prop的文件格式;
Android的属性系统是一种特殊的Action,这种Action以”on property:”为前缀;
在android 系统中,为统一管理系统的属性,设计了一个统一的属性系统。每个属性都有一个名称和值,他们都是字符串格式。属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性。在编译的过程中会将各种系统参数汇总到build.proc 以及default.proc 这两个文件中,主要属性集中在build.proc中。系统在开机后将读取配置信息并构建共享缓冲区,加快查询速度。另外一个方面,SettingsProvider会在系统第一次初始化时(刷机第一次启动)后,将从Defaults.xml中读取数据然后写入数据库Settings.db 目录。并构建一个缓冲系统供其他应用查询。
属性服务详解
5.4.2 关于属性系统中创建的Socket
这个socket主要用于客户端和服务端的通信,便于操作属性系统的key-value;
- 这里的服务端我们可以将其抽象理解为在inti.c中的start_property_service函数,在这个函数中,创建一个服务端的socket,类似于servicesocket,并在0666端口进行监听;
- 这里的客户端主要在system/core/libcutils/properties.c的property_ set的函数中,在一系列处理之后,会创建客户端的Socket,并连接服务端;
六: Home应用是如何启动的
- zygote中通过fork系统调用创建system_server进程
- system_server进程创建各种服务,如ActivityManagerService,PackageManagerService
- 系统服务启动后会注册到ServiceManager中,用于Binder通信;
- ActivityManagerService进入systemReady状态
6.1 关于Zygote
他是一个守护进程服务,所有其他的Dalvik虚拟机进程都是通过zygote fork出来的,这样便可以共享虚拟机内存和框架层资源;
6.2 关于Zygote的配置
在linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。
在系统启动脚本init.rc文件中,我们可以看到启动Zygote进程的脚本命令:
service zygote /system/bin/app_process
上述脚本表示要启动一个进程,名称为zygote, 可执行文件为/system/bin/app_process, –Xzygote /system/bin –zygote –start-system-server这些是传给zygote的参数;
app_process对应的源码在frameworks/base/cmds/app_process目录下,其入口函数main在文件app_main.cpp中
6.3 关于zygote启动位置的一些疑问
- 既然zygote是在init.rc中定义的守护进程,那为什么不在init中直接启动,而是在app_process中完成加载?
- 这是因为zygote不同于其他的守护进程,他是由Java语言实现,不能通过init进程的fork方式启动,因此需要在app_process完成加载工作;
6.4 关于app_main.cpp的main方法的解释
int main(int argc, char* const argv[])
{
if (!LOG_NDEBUG) {
String8 argv_String;
for (int i = 0; i < argc; ++i) {
argv_String.append(""");
argv_String.append(argv[i]);
argv_String.append("" ");
}
ALOGV("app_process main with argv: %s", argv_String.string());
}
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.
");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
这段函数主要作用是:
6.5 查看AppRuntime类的start方法
AppRuntime的实现代码在app_main.cpp中
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*
* Passes the main function two arguments, the class name and the specified
* options string.
*/
void AndroidRuntime::start(const char* className, const Vector& options, bool zygote)
{
ALOGD(">>>>>> START %s uid %d <<<<<<
",
className != NULL ? className : "(unknown)", getuid());
static const String8 startSystemServer("start-system-server");
/*
* 'startSystemServer == true' means runtime is obsolete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == startSystemServer) {
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
}
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /android does not exist.");
return;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
//const char* kernelHack = getenv("LD_ASSUME_KERNEL");
//ALOGD("Found LD_ASSUME_KERNEL='%s'
", kernelHack);
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
//查看onVmCreated方法体可以看出这是一个空方法体,采用多态形式实际上调用的是AppRuntime的onVmCreated方法
onVmCreated(env);
该方法主要做了如下工作
- 创建Dalvik虚拟机 startVm(&mJavaVM, &env, zygote)
- 注册JNI方法 startReg(env)
6.6 startVm(&mJavaVM, &env, zygote)
- 通过属性系统获取虚拟机配置信息,设置虚拟机参数
- 调用JNI_CreateJavaVM创建虚拟机
我们可以通过dalvik/docs/dexopt/html查看虚拟机详细信息;或者通过adb shell dalvikvm查看
6.7 startReg(env)
- 正如之前说的日志系统,Java层可以不用加载so变实现native方法调用,其实正是这里采用的注册方法关联了Native方法和JNI实现方法
- startReg方法主要调用register_jni_procs方法。register_jni_procs方法传入RegJNIRec类型,通过查看类型的定义
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
使用REG_JNI宏,将函数名传给RegJNIRec, 这些函数最终都调用了RegisterMethodsOrDie方法完成JNI注册;关于RegisterMethodsOrDie方法,在前面的文章中已经有了讲解
Android运行时注册的共享库为libandroid_runtime.so; 在虚拟机创建的过程中已经完成加载,其他虚拟机是通过zygote fork的方式创建,则会共享libandroid_runtime.so
6.8 CallStaticVoidMethod(startClass, startMeth, strArray);
- 在AppRuntime类的start方法中最终会调用CallStaticVoidMethod方法,该方法是个JNI函数,其调用的是ZygoteInit的main方法;此时Java的代码正式出现;
- CallStaticVoidMethod的声明在jni.h中,但是你却找不到他的实现;其实CallStaticVoidMethod的方法是使用宏来定义的;同样的在jni.h中,我们可以看见
#define CALL_STATIC_TYPE_METHODA(_jtype, _jname)
__NDK_FPABI__
_jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID,
jvalue* args)
{ return functions->CallStatic##_jname##MethodA(this, clazz, methodID,
args); }
这里我们就不做过多研究,只要知道最终调用的是调用的是ZygoteInit的main方法即可
6.9 ZygoteInit.java的main方法
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
ZygoteHooks.startZygoteNoThreadCreation();
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
try {
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
RuntimeInit.enableDdms();
SamplingProfilerIntegration.start();
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
zygoteServer.registerServerSocket(socketName);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
SamplingProfilerIntegration.writeZygoteSnapshot();
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
gcAndFinalize();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Trace.setTracingEnabled(false);
Zygote.nativeUnmountStorageOnInit();
Seccomp.setPolicy();
ZygoteHooks.stopZygoteNoThreadCreation();
if (startSystemServer) {
/**
* Prepare the arguments and fork for the system server process.
* zygote通过folk方式创建system_server进程,其方法为Zygote.forkSystemServer;forkSystemServer方法系统会检查system server进程是否启动成功,如果启动失败,则导致zygote重启;system server负责构建Native System Service和Java System Service,如果启动失败,整个java 世界也无从谈起
*/
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
我们看下registerServerSocket的实现
/**
* Registers a server socket for zygote command connections
*
* @throws RuntimeException when open fails
*/
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
在这里使用了LocalServerSocket.java,如上调用LicalServerSocket.java的构造函数
/**
* Create a LocalServerSocket from a file descriptor that's already
* been created and bound. listen() will be called immediately on it.
* Used for cases where file descriptors are passed in via environment
* variables
*
* @param fd bound file descriptor
* @throws IOException
*/
public LocalServerSocket(FileDescriptor fd) throws IOException
{
impl = new LocalSocketImpl(fd);
impl.listen(LISTEN_BACKLOG);
localAddress = impl.getSockAddress();
}
至此,我们已经为zygot创建了一个类型为LocalServerSocket的socket
- 参考zygoteinit.java main方法里面的注释,我们简单对该方法做个整理
6.9.1 new ZygoteServer对象,ZygoteServer类主要作用是新建zygote进程的server socket
6.9.2 调用ZygoteServer对象的registerServerSocket的方法,生成LocalServerSocket类型的server socket,其应该为unix上的socket,并监听50端口
6.9.3 调用preload方法,该方法将
-调用preloadClasses方法,预加载/system/etc/preloaded-classes文件里面的类
-调用preloadResources方法,预加载com.android.internal.R.array.preloaded_drawables和com.android.internal.R.array.preloaded_color_state_lists资源文件,这两个资源定义在frameworksasecore
es
esvaluesArrays.xml中;
Arrays.xml里面定义的资源最终会被生成到framework-res.apk中,这样其他进程就可以共享资源了,使用方法为:android:background=”@android:drawable/ic_menu_help”
6.9.4 调用startSystemServer方法,该方法调用过程如下
1) 通过fork的方式开启system_server进程,forkSystemServer方法系统会检查system server进程是否启动成功,如果启动失败,则导致zygote重启;system server负责构建Native System Service和Java System Service,如果启动失败,整个java 世界也无从谈起
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities)
2)调用handleSystemServerProcess方法,该方法主要调用ZygoteInit.zygoteInit方法
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote")
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit")
//重定向log系统
RuntimeInit.redirectLogStreams()
//一些初始化设置
RuntimeInit.commonInit()
//nativeZygoteInit为native方法,其在AndroidRuntime.cpp总,有具体实现;最终调用到AppRuntime的onZygoteInit方法,该方法开启了system_server的binder通信通道
ZygoteInit.nativeZygoteInit()
//applicationInit将调用invokeStaticMain方法,invokeStaticMain方法将采用反射的方式获取frameworksaseservicesjavacomandroidserver、SystemServer.java,然后得到main方法,注意此处并没有调用main方法;并抛出MethodAndArgsCaller异常;该异常在zygoteinit.java的main函数中有捕获,当main方法捕获到该异常之后,调用该异常的run方法,传入的参数是SystemServer.java的main方法,此时才是真正执行main方法的地方;这样做的好处是跳出调用栈,直接返回到zygoteinit的main方法中
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader)
}
7.0 SystemServer.java main方法详解
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
mFactoryTestMode = FactoryTest.getMode();
mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
}
private void run() {
try {
......
Looper.prepareMainLooper();
System.loadLibrary("android_servers");
performPendingShutdown();
createSystemContext();
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
......
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
我们主要分析一下该run方法,在该方法中会涉及到启动Home App
1)设置系统时间,时区
2)设置系统属性
3)加载android_servers.so
4 ) 调用createSystemContex方法,创建sytem的context;
activityThread.getSystemContext()返回的是ContextImpl对象,ContextImpl继承自Context
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
}
5)创建SystemServiceManager对象,(SystemServer进程主要是用来构建系统各种service服务的,而SystemServiceManager就是这些服务的管理对象;)创建完对象之后调用LocalServices.addService添加到LocalServices.java的一个ArrayMap中
6) 调用startBootstrapServices开启boot级service
在启动service之前先介绍下SystemServiceManager对象的startService方法
该方法传入class类型,通过反射的方式拿到传入类的实例,拿到对应类实例之后,将其添加到ArrayList类型的mServices中进行生命周期管理,并同时调用该实例的onStart方法
private final ArrayList mServices = new ArrayList();
现在来看下 startBootstrapServices方法的执行流程
a: 通过 SystemServiceManager.startService(Installer.class)创建Install的systemservice,Install是系统安装apk时的一个服务类;
b: 通过 SystemServiceManager.startService方法开启ActivityManagerService,并为其设置SysServiceManager和Installer
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService()
mActivityManagerService.setInstaller(installer)
c: 开启PowerManagerService 该类用来管理电源
d: 开启LightsService,该类用来管理LED和背光
e: 开启DisplayManagerService,显示管理服务DisplayManagerService,支持多种显示类型的多个显示器的镜像显示,包括内建的显示类型(本地)、HDMI显示类型以及支持WIFI Display 协议( MIRACAST),实现本地设备在远程显示器上的镜像显示。
f: 开启UserManagerService
g: 开启PackageManagerService,这个不是通过startservice启动,而是通过如下启动
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore)
mFirstBoot = mPackageManagerService.isFirstBoot()
mPackageManager = mSystemContext.getPackageManager()
7)调用startCoreServices启动系统核心的服务
private void startCoreServices() {
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class)
// Tracks application usage stats.
mSystemServiceManager.startService(UsageStatsService.class)
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class))
// Tracks whether the updatable WebView is in a ready state and watches for update installs.
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class)
}
a. 调用startservice开启BatteryService
b. 调用startservice开启UsageStatsService
c. 调用startservice开启WebViewUpdateService
8)调用startOtherServices() 主要用于启动一些非紧要或者是非需要及时启动的服务
8.0 如何显示Home App的
在上面的讲解中,我们调用了startOtherServices方法,该方法将调用mActivityManagerService.systemReady方法,告诉系统已经好了,可以显示Home App了
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
Slog.i(TAG, "Making services ready");
......
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
......
}
});
systemReady方法将调用startHomeActivityLocked启动Home App
startHomeActivityLocked(currentUserId, "systemReady");
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
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));
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
由于launcher是一个apk,在之前的packagemanagerserver已经对其进行解析,因此可以获得对应的intent信息,接着调用ActivityStarter.java startHomeActivityLocked方法,该方法调用startActivityLocked方法
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
mSupervisor.moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
startActivityLocked(null , intent, null ,
null , aInfo, null , null ,
null , null , null ,
0 , 0 , 0 , null ,
0 , 0 , 0 , null ,
false , false , null ,
null , null );
if (mSupervisor.inResumeTopActivity) {
mSupervisor.scheduleResumeTopActivities();
}
}
在startActivityLocked有一个重要的方法如下
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
该方法主要作用是在启动activity的时候,PMS会去找清单文件,是否有注册的Activity;
该方法实际上调用的是PackageManagerService(PMS)的resolveIntent方法,
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
...
final ResolveInfo bestChoice =
chooseBestActivity(intent, resolvedType, flags, query, userId);
return bestChoice;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
chooseBestActivity方法会根据priority优先级来判断来选择最好的一个activity,这个priority会在launcher 的manifest.xml中进行配置;当查询到这个activity之后,Launcher App就被启动起来,接着完成activity的启动过程,即进行activity相应生命周期的流程,展示UI;
在ActivityStarter.java中的startActivityLocked方法中,会调用startActivityUnchecked方法
这个方法处理了Activity的启动模式,比如是否需要新建一个任务栈,栈里面是否需要复用已经存在的Activity实例等等。而且启动模式还要配合flag,比如说NEW_TASK等。并且在清单文件里面的启动模式的配置要优先于flags
在startActivityUnchecked方法体内部有如下关键代码
ActivityStack.logStartActivity(
EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.task)
mTargetStack.mLastPausedActivity = null
sendPowerHintForLaunchStartIfNeeded(false )
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions)
ActivityStack是activity的栈的管理类;调用ActivityStack类的startActivityLocked之后;