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

本文基于Android10.0的源码。
由于google团队在对framework层代码进行大量重构,所以代码变动还是挺大的。

常见基础问题:

SystemServer系统服务进程是如何创建的?Launcher进程如何被创建的?
是由Zygote进程fork而来

Launcher启动入口在哪儿?
ActivityManagerService的systemReady函数就是启动Launcher的入口。

系统如何识别Launcher应用?
android.intent.category.HOME

如何开发一个桌面Launcher应用?
android.intent.category.HOME;
android.intent.category.DEFAUlT。

Android应用进程的的入口类?
ActivityThread

为什么Activity必须在清单文件中注册?
ActivityStarter会做各种启动前检查。

一、Android系统架构及开机流程

Google官方提供的经典分层架构图:
在这里插入图片描述
从下往上依次分为5层:

  • Linux内核层
  • HAL层(硬件抽象层)
  • 系统运行库层(系统Native库和Android运行时环境)
  • FramWork层(Java框架层)
  • Application层(包括Systema Apps和三方App)

Google提供的5层架构图很经典,但为了更进一步透视Android系统架构,本文更多的是以进程的视角,以分层的架构来诠释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进程孵化而来的。

Linux Kernel完成系统设置后,会首先在系统中寻找init.rc文件,并启动init进程。

由于init中都是C语言代码,看不懂,不深入看源码了。简单了解下启动zygote的部分。在init.zygote.rc文件中,zygote服务定义如下:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd

通过init_parser.cpp完成整个service解析工作,此处就不详细展开讲解析过程,该过程主要工作是:

创建一个名叫”zygote”的service结构体;
创建一个用于socket通信的socketinfo结构体;
创建一个包含4个onrestart的action结构体。

Zygote服务会随着main class的启动而启动,退出后会由init重启zygote,即使多次重启也不会进入recovery模式。zygote所对应的可执行文件是/system/bin/app_process,通过调用pid =fork()创建子进程,通过execve(svc->args[0], (char**)svc->args, (char**) ENV),进入App_main.cpp的main()函数。故zygote是通过fork和execv共同创建的

2.2.Zygote进程

在Zygote进程创建完成之后,会进入java世界,即ZygoteInit.java。

问:我们知道Java调用C++可以通过JNI。那么C++是如何转到Java的,也就是说ZygoteInit.java这个类是如何被调用的?
答:在java中,class文件是由ClassLoader来加载的,但实际上,ClassLoader在加载java文件的过程中,也是通过C++来完成的(Bootstrp loader就是用C++写的,具体可以去看java类加载过程及机制,Java类加载器ClassLoader总结),所以C++如果想要访问java文件的话,是非常轻松的。如下:
在这里插入图片描述
接下里看ZygoteInit.java都做了些什么
在这里插入图片描述
这里第一步预加载的有系统的class文件,系统的资源文件,系统的动态库,因为我们所开发的应用在运行时会使用到大量的系统资源,如果这些资源在app启动的时候才加载,势必会造成app启动缓慢,而如果在Android系统启动的时候就将这些资源提前预加载,就可以达到提高启动app速度。

第三步这里的Socket服务是用来接受来自ActivityManagerService申请进程创建的请求的。然后就会进入到阻塞状态,等待连接。

SystemServer进程创建后会做什么,看一下SystemServer.java这个类:

先看main方法:

/**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }

接着看run()方法,主要是创建了系统服务的管理者,并启动了一些服务

 private void run() {
	...
	 // Create the system service manager. //创建系统服务的管理者
	 mSystemServiceManager = new SystemServiceManager(mSystemContext);
	...
	 // Start services.  
        try {
            t.traceBegin("StartServices");
            //启动引导服务
            startBootstrapServices(t);		
            //启动核心服务
            startCoreServices(t);
            //启动其它一些服务			
            startOtherServices(t);			
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            t.traceEnd(); // StartServices
        }
 }

在SystemServer中,启动了非常多的服务,这些服务都交给SystemServiceManager来管理。
在这里插入图片描述
其中其它服务一共有90+。这些服务都是通过startService方式启动,并注册到SystemServiceManager当中的。如:

	//启动包管理服务
 	mSystemServiceManager.startService(new OverlayManagerService(mSystemContext));
	//启动传感器服务
	mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext));

这些系统服务就构成了Android的FramWork层。为上层的app开发和运行提供了保障。所以SystemServer这个进程是在系统的启动流程中,我们需要重点了解的。

当这些服务启动完成之后;其中的ActivityManagerService最终会调用systemReady()方法。

    	// 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");
            t.traceBegin("StartActivityManagerReadyPhase");
            mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
            t.traceEnd();
            t.traceBegin("StartObservingNativeCrashes");
            try {
                mActivityManagerService.startObservingNativeCrashes();
            } catch (Throwable e) {
                reportWtf("observing native crashes", e);
            }
            t.traceEnd();

注意systemReady这个方法,注释的意思大概是:我们是时候去通知ActivityManager去启动第三方应用了。当三方应用真的可以运行的时候会通知我们,以便我们完成初始化。括号里面的内容大概是:在它(三方应用)启动之前会先启动launcher应用。

Android 系统启动流程总结:

第一步:手机开机后,引导芯片启动,引导芯片开始从固化在ROM里的预设代码执行,加载引导程序到到RAM,BootLoader检查RAM,初始化硬件参数等功能;

第二步:硬件等参数初始化完成后,进入到Kernel层,Kernel层主要加载一些硬件设备驱动,初始化进程管理等操作。在Kernel中首先启动swapper进程(pid=0),用于初始化进程管理、内管管理、加载Driver等操作,再启动kthread进程(pid=2),这些linux系统的内核进程,kthread是所有内核进程的鼻祖;

第三步:Kernel层加载完毕后,硬件设备驱动与HAL层进行交互。初始化进程管理等操作会启动init进程 ,这些在Native层中;

第四步:init进程(pid=1,init进程是所有进程的鼻祖,第一个启动)启动后,会启动adbd,logd等用户守护进程,并且会启动servicemanager(binder服务管家)等重要服务,同时孵化出zygote进程,这里属于C++ Framework,代码为C++程序;

第五步:zygote进程是由init进程解析init.rc文件后fork生成,它会加载虚拟机,启动System Server(zygote孵化的第一个进程);SystemServer负责启动和管理整个Java Framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务;

第六步:zygote同时会启动相关的APP进程,它启动的第一个APP进程为Launcher,然后启动Email,SMS等进程,所有的APP进程都有zygote fork生成。

到这里,系统开机到桌面应用准备就完成了,接下来就是launcher应用启动流程分析。

三、Launcher启动流程

3.1.Launcher启动流程关键类介绍:

ActivityManagerService
负责管理四大组件和进程,包括生命周期和状态切换。它的systemReady()方法,正是launcher应用启动的入口。

ActivityTaskManagerService
把原先在ActivityManagerService中负责Activity管理和调度等工作转移到了这里。ActivityTaskManagerService是Android10中新增的。

RootActivityContainer:
调用packageManagerService中去查询手机系统中已安装的所有的应用,哪一个符合launcher标准,且得到一个Intent对象,并交给ActivityStarter。

ActivityStarter
做启动之前的各项检查,比如Activity是否有在清单文件注册,Class文件是否存在等等。

ActivityRecord:
在Server端对activity的一种映射,记录和存储activity的信息。

TaskRecord
记录一个或多个ActivityRecord的实例

ActivityStack:
应用的任务栈的管理者

ActivityStackSupervisor
负责所有Activity栈的管理,包括launcher和非launcher应用。

ProcessList:
把原先在AMS中启动进程的工作转移到这里,是Android10中新增的。

Instrumentation:
负责调用Activity和Application生命周期。

ActivityTaskManagerInternal:
是由ActivityTaskManagerService对外提供的一个抽象类,真正的实现是在 ActivityTaskManagerService#LocalService

ActivityThread:
管理应用程序进程中主线程的执行

TransactionExecutor:
主要作用是执行ClientTransaction

ClientLifecycleManager:
生命周期的管理调用

3.2.launcher启动流程分析:

Launcher的启动由三部分启动:

1.SystemServer完成启动Launcher Activity(符合launcher应用的最佳Activity)的调用

2.Zygote fork出launcher进程。

3.ActivityThread的main()方法,完成最终Launcher的onCreate操作

3.2.1.第一阶段:SystemServer启动Launcher应用调用阶段

调用栈如下:
在这里插入图片描述

前面我们知道了ActivityManagerService的systemReady()正是Launcher启动的入口。在其中会去调用startHomeOnAllDisplays()来启动Launcher.

[ActivityManagerService.java]中代码:这个方法大概有200多行,只展示关键点:


public void systemReady(final Runnable goingCallback, TimingsTraceLog 
traceLog) {
    ...
    //启动HomeActivity(即Launcher应用的入口Activity):本意是在所有的屏幕上启动桌面应用,因为Android10.0开始是支持多屏幕的,比如手机屏幕,虚拟投屏,外接屏幕
    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
    ...
}

这里的mAtmInternal是ActivityTaskManagerInternal,是一个抽象类。

/**
 * Activity Task manager local system service interface.
 * @hide Only for use within system server
 */
public abstract class ActivityTaskManagerInternal {
	...
}

真正的实现是在ActivityTaskManagerService的内部类LocalService中。

这里有个阅读源码的技巧,一般以Internal结尾的抽象类,其实现类如下图所示,都在其对应的Service结尾的内部类LocalService中。
在这里插入图片描述
所以我们可以找到ActivityTaskManagerService的内部类LocalService,它继承自ActivityManagerInternal,确实有startHomeOnAllDisplays()方法。这里最终调用到RootActivityContainerstartHomeOnDisplay()方法

   final class LocalService extends ActivityTaskManagerInternal {
	   ...
	      @Override
        public boolean startHomeOnAllDisplays(int userId, String reason) {
            synchronized (mGlobalLock) {
                return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
            }
        }

	   ...
   }

前面提到RootActivityContainer的作用是:调用packageManagerService中去查询手机系统中已安装的所有的应用,哪一个符合launcher标准,且得到一个Intent对象,并交给ActivityStarter

这里会一直调用到RootActivityContainer.startHomeOnDisplay()方法:


boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
    boolean fromHomeKey) {
    ...
     if (displayId == DEFAULT_DISPLAY) {
        //关键点1:构建一个category为CATEGORY_HOME的Intent,表明是HomeActivity(我觉得这个说法太含混,应该表明是构建一个符合launcher应用的Intent)
        homeIntent = mService.getHomeIntent();
        //关键点2:通过PMS从系统所用已安装的引用中,找到一个符合homeIntent的Activity
        aInfo = resolveHomeActivity(userId, homeIntent); 
    } 
    ...
    //关键点3:启动launcher
    mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
        displayId);
    return true;
}

获取的displayId为DEFAULT_DISPLAY, 通过getHomeIntent 来构建一个category为CATEGORY_HOME的Intent,表明是一个符合launcher应用的Intent;然后通过resolveHomeActivity()从系统所用已安装的引用中,找到一个符合该Intent的Activity,最终调用startHomeActivity()来启动Activity

然后看下ActivityTaskManagerService.getHomeIntent()方法:主要就是构建一个
符合launcher应用的Intent。

Intent getHomeIntent() {
    Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
    intent.setComponent(mTopComponent);
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    //不是生产模式,add一个CATEGORY_HOME
    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        intent.addCategory(Intent.CATEGORY_HOME);//表明是符合launcher的Intent
    }
    return intent;

RootActivityContainer.resolveHomeActivity()方法:


ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
    final int flags = ActivityManagerService.STOCK_PM_FLAGS;
    final ComponentName comp = homeIntent.getComponent(); //系统正常启动时,component为null
    ActivityInfo aInfo = null;
    ...
        if (comp != null) {
            // Factory test.
            aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
        } else {
            //系统正常启动时,走该流程
            final String resolvedType =
                    homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
            
            //resolveIntent做了两件事:1.通过queryIntentActivities来查找符合HomeIntent需求Activities
            //2.通过chooseBestActivity找到最符合Intent需求的Activity信息
            final ResolveInfo info = AppGlobals.getPackageManager()
                    .resolveIntent(homeIntent, resolvedType, flags, userId);
            if (info != null) {
                aInfo = info.activityInfo;
            }
        }
    ...
    aInfo = new ActivityInfo(aInfo);
    aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
    return aInfo;
}

通过Binder跨进程通知PackageManagerService从系统所用已安装的引用中,找到一个符合HomeItent的Activity。

然后是ActivityStartController.startHomeActivity()方法:
这个类唯一的作用就是配置activity启动前的一些信息,并把这些信息传递给ActivityStart去做启动。


void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
    ....
    //关键点:obtainStarter方法返回一个 ActivityStarter对象,它负责 Activity 的启动
    mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
            .setOutActivity(tmpOutRecord)
            .setCallingUid(0)
            .setActivityInfo(aInfo)
            .setActivityOptions(options.toBundle())
            .execute(); // 关键点:execute()会触发 ActivityStarter的execute方法
    mLastHomeActivityStartRecord = tmpOutRecord[0];
    final ActivityDisplay display =
            mService.mRootActivityContainer.getActivityDisplay(displayId);
    final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
    if (homeStack != null && homeStack.mInResumeTopActivity) {
        //如果home activity 处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复(以避免递归恢复),
        //并将保持这种状态,直到有东西再次触发它。我们需要进行另一次恢复。
        mSupervisor.scheduleResumeTopActivities();
    }
}

ActivityStarter.execute()方法:

int execute() {
    ...
    if (mRequest.mayWait) {
        return startActivityMayWait(...)
    } else {
         return startActivity(...) 
    }
    ...
}

由于obtainStarter方法没有调用setMayWait的方法做任何配置,因此mRequest.mayWait为false,会走startActivity流程

ActivityStarter. startActivity()方法:
在这里插入图片描述
这个方法主要用来做activity启动之前的安全校验

关键点:int err = ActivityManager.START_SUCCESS
在这里插入图片描述
这里的caller,只有当应用进程创建完成之后,Server端才能拿到这个对象不为空的值,由于此时launcher应用的进程还未创建,所以此时caller对象一定为空。

还会做一些其它的校验,包括后台启动activity,activity启动权限等,其它如:
在这里插入图片描述
接着会调用到ActivityStarter.startActivityUnchecked方法
在这里插入图片描述
其中computeLaunchingTaskFlags(),是根据activity的launcher mode和intent.flag计算出activity的入栈方式。computeSourceStack()计算从哪个任务栈启动该activity。

这个方法一路会调用到

RootActivityContainer.resumeFocusedStacksTopActivities()方法:


boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ...
    //如果秒表栈就是栈顶Activity,启动resumeTopActivityUncheckedLocked()
    if (targetStack != null && (targetStack.isTopStackOnDisplay()
        || getTopDisplayFocusedStack() == targetStack)) {
    result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    ...
    if (!resumedOnDisplay) {
        // 获取栈顶的ActivityRecord
        final ActivityStack focusedStack = display.getFocusedStack();
        if (focusedStack != null) {
            //最终调用startSpecificActivityLocked()
            focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
    }
  }
}

中间还会走到ActivityStack中调用方法,如:
在这里插入图片描述
由于此时launcher进程没有创建完成,所以走到else中,然后调用到
在这里插入图片描述

接着看ActivityStackSupervisor.startSpecificActivityLocked()


void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    ...
    //最终调用到AMS的startProcess()
    final Message msg = PooledLambda.obtainMessage(
    //这里的::是java8中的一个关键字,主要解决java8之前方法不能作为其它方法参数的问题
            ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
            r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
    mService.mH.sendMessage(msg);
    ...
}

ActivityManagerService.startProcess()方法:开始创建进程
在这里插入图片描述
然后调用startProcessLocked方法,
在这里插入图片描述
在startProcessLocked中,又进一步把进程创建工作委派给了ProcessList,这是Android10中对FrameWork进行改造而引入的,在老的版本中对进程的创建是在AMS中去发起请求的,谷歌团队认为AMS已经非常臃肿了(改造前2.8W行,改造后1.9W行),所以引入ProcessList专门进行进程的创建。

接着看ProcessList.startProcessLocked方法:
在这里插入图片描述
主要作用是,在进程创建之前,会配置一些必要的参数,比如版本号之类的。
接着,这个方法中有一个非常重要的参数:
在这里插入图片描述
entryPoint就是新进程的入口。

在创建进程的时候,在这里强制指定为android.app.ActivityThread.

所以,所有Android应用的进程入口是ActivityThread。并不是我们通常理解的application。

创建进程所需要的参数配置完成后,最终会走到ZygoteProcess
在这里插入图片描述
此时还是处于SystemServer进程。这个类的目的是创建本地socket连接对象,并且连接远在Zygote进程的socket服务,然后通过字符输入流,把创建进程所需要的参数发送过去,进程创建完成后,会根据传递的新进程的入口类,由zygotInit反射执行。

创建进程的调用栈如下:
在这里插入图片描述

3.2.2.第二阶段:Zygote fork一个Launcher进程的阶段

Zygote的启动过程我们前面有简单了解。SystemServer的AMS服务向启动launcher发起一个fork请求,Zygote进程通过Linux的fork函数,孵化出一个新的进程。

由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的Launcher程序进程可以在内部获取一个Java虚拟机的实例拷贝。fork采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。

Zygote的调用栈如下:
在这里插入图片描述
ZygoteInit.main():

public static void main(String argv[]) {
    ...
    Runnable caller;
    ....
    if (startSystemServer) {
        //Zygote Fork出的第一个进程 SystmeServer
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
 
        if (r != null) {
            r.run();
            return;
        }
    }
    ...
    //循环等待fork出其他的应用进程,比如Launcher
    //最终通过调用processOneCommand()来进行进程的处理
    caller = zygoteServer.runSelectLoop(abiList);
    ...
    if (caller != null) {
        caller.run(); //执行返回的Runnable对象,进入子进程
    }
}

Zygote先fork出SystemServer进程,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程,比如Launcher。

ZygoteConnection.processOneCommand()


Runnable processOneCommand(ZygoteServer zygoteServer) {
    int pid = -1;
    ...
    //Fork子进程,得到一个新的pid
    /fork子进程,采用copy on write方式,这里执行一次,会返回两次
    ///pid=0 表示Zygote  fork子进程成功
    //pid > 0 表示子进程 的真正的PID
    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
            parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
            parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
            parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
    ...
    if (pid == 0) {
        // in child, fork成功,第一次返回的pid = 0
        ...
        return handleChildProc(parsedArgs, descriptors, childPipeFd,
                parsedArgs.mStartChildZygote);
    } else {
        //in parent
        ...
        childPipeFd = null;
        handleParentProc(pid, descriptors, serverPipeFd);
        return null;
    }
}

通过forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理.

ZygoteConnection.handleChildProc():

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
        FileDescriptor pipeFd, boolean isZygote) {
    ...
    if (parsedArgs.mInvokeWith != null) {
        ...
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        if (!isZygote) {
            // App进程将会调用到这里,执行目标类的main()方法
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        }
    }
}

进行子进程的操作,最终获得需要执行的ActivityThread的main()

然后把之前传来的"android.app.ActivityThread" 传递给findStaticMain:

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    ...
    // startClass: 如果AMS通过socket传递过来的是 ActivityThread
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

通过反射,拿到ActivityThread的main()方法:

protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class<?> cl;
 
    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }
 
    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        throw new RuntimeException(
                "Missing static main on " + className, ex);
    } catch (SecurityException ex) {
        throw new RuntimeException(
                "Problem getting static main on " + className, ex);
    }
 
    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }
    return new MethodAndArgsCaller(m, argv);
}

把反射得来的ActivityThread main()入口返回给ZygoteInit的main,通过caller.run()进行调用:

static class MethodAndArgsCaller implements Runnable {
    /** method to call */
    private final Method mMethod;
 
    /** argument array */
    private final String[] mArgs;
 
    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }
 
    //调用ActivityThread的main()
    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

到这里,就执行到了ActivityThread的main()方法。

3.2.3.第三阶段:进入ActivityThread的main(),完成最终Launcher的onCreate操作

Zygote fork出了Launcher的进程,并把接下来的Launcher启动任务交给了ActivityThread来进行,接下来我们就从ActivityThread main()来分析Launcher的创建过程。
在这里插入图片描述
ActivityThread.main():Java程序的入口,直接找到main方法。


public static void main(String[] args) {
 	 ...
  	//初始化looper
    Looper.prepareMainLooper();
  	...
    ActivityThread thread = new ActivityThread();
    //建立Binder通道 (创建新线程)
    thread.attach(false, startSeq);
  	...
  	//主线程开始轮训,如果退出,说明程序关闭
    Looper.loop();
}

正式因为在进程的入口方法里面开始了消息队列的轮训,所以主线程才有了消息分发的机制。

ActivityThread的attach会一直调用到AMS的attachApplication方法。

ActivityManagerService.attachApplication()


public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
    	//通过Binder获取传入的pid信息
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
        ...
        ...
    }
}

在这个方法中,又调用一系列方法,这里省略大量代码。最终主要做了两件事:
1.调度ActivityThread创建Application,并调用了application的onCreate()方法。如图:
在这里插入图片描述

2.继续启动进程创建之前已经加入任务栈的那个Activity,也就是Launcher应用的第一个Activity。
在这里插入图片描述mAtmIntetnal.attachApplication(…),这里的mAtmIntetnal是ActivityTaskManagerInternal。这个方法的作用就是启动launcher应用的第一个Activity。根据前面讲的阅读源码技巧,这里可以找到该方法的实现在ActivityTaskManagerService中:
在这里插入图片描述
这里进一步交给了RootActivityContainer,接着看,这里很关键:
在这里插入图片描述
终于层层调用到ActivityStackSupervisor.java的 **realStartActivityLocked()**进行Activity的启动了。

ActivityStackSupervisor.realStartActivityLocked():


boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
  try {
            //创建一个启动Activity的事务对象
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);
      		//往事务里面添加一个任务,叫LaunchActivityItem
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                    r.icicle, r.persistentState, results, newIntents,
                    dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                            r.assistToken));
 
      ...
            final ActivityLifecycleItem lifecycleItem;
            //这里就是上面提到的andResume参数,只有当该Activity在栈顶才为True.
            if (andResume) {
            //执行Activity的resume生命周期方法
                lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
            } else {
             //执行Activity的pause生命周期方法
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);
		 	//开始事务的执行
 			mService.getLifecycleManager().scheduleTransaction(clientTransaction);
  ...

}

这里的LaunchActivityItem,ResumeActivityItem等也是在Android10.0的改动,把Activity的生命周期拆分成ActivityLifecycleItem,根据不同的状态让不同的ActivityLifecycleItem去执行不同的activity的生命周期,这种设计模式叫做状态机
在这里插入图片描述
在状态机模式中,将每一个条件的分支,放入一个独立的类中,去除过多的 if else 分支语句。

接着看上面,一旦执行了scheduleTransaction开启事务,就会调用到LaunchActivityItem的excute方法。然后会调用到ClientTranscationHandler的handlerLaunchActivity方法。
在这里插入图片描述
我们知道ClientTranscationHandler是ActivityThread的父类,是一个抽象类,所以直接找到ActivityThread中去查看,在ActivityThread的handlerLaunchActivity中又会调用到performLaunchActivity方法:

在这里插入图片描述
这个方法就会去真正的启动Activity,并且返回一个Activity对象。当得到这个Activity的实例对象之后,接着看该方法下面的代码:

在这里插入图片描述
跟进这个方法:


public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity); //activity onCreate的预处理
    activity.performCreate(icicle, persistentState);//执行onCreate()
    postPerformCreate(activity); //activity onCreate创建后的一些信息处理
}

performCreate()主要调用Activity的onCreate():


final void performCreate(Bundle icicle, PersistableBundle persistentState) {
  ...
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
  ...
}
同理:如果还往事务中添加了ResumeActivityItem,相应的也会执行到Activity的onResume生命周期。

好了,到这里终于看到我们熟悉的Activity的onCreate(),到这里Launcher应用才启动完成,Launcher被真正创建起来。

  • 17
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值