目录
2.3.1、Zygote 处理 SystemServer 进程
2.3.1.2、进入 System Server 的 main 方法
2.3、SystemServer 处理过程
SystemServer 进程主要用于创建系统服务,我们熟知的 AMS 、 WMS 和 PMS 都是由它来创建的,本书后面的章节会介绍 AMS 和 WMS ,因此掌握 SystemServer 进程是如何启动的,它在启动时做了哪些工作是十分必要的 。
2.3.1、Zygote 处理 SystemServer 进程
在 2.2 节中讲到了 Zygote 进程启动了 SystemServer 进程 , 本节来学习 Zygote 是如何处理 SystemServer 进程的,时序图如图 2-2 所示。
在 Zygotelnit. java 的 startSystemServer 方法中 启动了 SystemServer 进程 ,如下所示 :
frameworks/base/core/java/com/android/internal/os/Zygotelnit.java
private static boolean startSystemServer ( String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException{
...
//当前运行在 SystemServer 进程中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//关闭 Zygote 进程创建的 Socket
zygoteServer.closeServerSocket(); //1
handleSystemServerProcess(parsedArgs); //2
}
return true;
}
SystemServer 进程复制了Zygote进程的地址空间,因此也会得到Zygote进程创建的Socket , 这个 Socket 对于 SystemServer 进程没有用处 , 因此, 需要注释 1 处的代码来关闭该 Socket,接着在注释 2 处调用 handleSystemServerProcess 方法来启动 SystemServer 进程。handleSystemServerProcess 方法的代码如下所示 :
frameworks/base/core/java/com/android/internal/os/Zygotelnit.java
private static void handleSystemServerProcess (ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller{
...
if(parsedArgs.invokeWith != null) {
...
}else{
ClassLoader cl = null ;
if (systemServerClasspath != null){
cl = createPathClassLoader(systemServerClasspath, parsedArgs.
targetSdkVersion) ;//l
Thread.currentThread().setContextClassLoader(cl);
}
Zygoteinit.zygoteinit(parsedArgs.targetsdkVersion,parsedArgs.remainingArgs,cl);//2
}
}
在注释 1 处创建了 PathClassLoader ,关于 PathC!assLoader 将在第 12 章进行介绍。在注释 2 处调用了 Zygotelnit 的 zygotelnit 方法,代码如下所示 :
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");
Runtimeinit.redirectLogStreams();
Runtimeinit.commoninit();
// 启动 Binder 线程池
Zygoteinit.nativeZygoteInit(); //1
// 进入 SystemServer 的 main 方法
Runtimeinit.applicationinit (targetSdkVersion, argv, classLoader); //2
}
在注释 1 处调用 nativeZygotelnit 方法, 一看方法的名称就知道i周用的是 Native 层的代码,用来启动 Binder 线程池 ,这样 SystemServer 进程就可以使用 Binder 与其他进程进行通信了。注释 2 处是用于进入 SystemServer 的 main 方怯,现在分别对注释 1 和注释 2 的内容进行介绍。
2.3.1.1、启动 Binder 线程池
nativeZygotelnit 是一个 Native 方怯,因此我们先要了解它对应的 JNI 文件,不了解 JNI的可以查看第 9 章内容,如下所示:
frameworks/base/core/jni/AndroidRuntime.cpp
int register_com android_internal_os_Zygoteinit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{" nativeZygoteinit", "()V",
(void*) com_android_internal_os_Zygoteinit_nativeZygoteinit},
};
return jniRegisterNativeMethods(env, "com/android/internal/os/Zygoteinit",
methods, NELEM(methods));
}
通过 JNI 的 gMethods 数组,可以看出 nativeZygotelnit 方法对应的是 JNI 文件AndroidRuntime.cpp 的 com android_ internal_os_zygotelnit_nativeZygotelnit 函数:
frameworks/base/core/jni/AndroidRuntime.cpp
statiC void com_android_internal_os_Zygoteinit_nativeZygoteinit(JNIEnv* env,jobject clazz)
{
gCurRuntime -> onZygoteInit();
}
这里 gCurRuntime 是 AndroidRuntime 类型的指针,具体指向的是 AndroidRuntime 的子类 AppRuntime ,它在 app_ main.cpp 中定义,我们接着来查看 AppRuntime 的 onZygotelnit方法,代码如下所示:
frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV ("App process: starting thread pool. \n");
proc -> startThreadPool(); //1
}
注释 1 处的代码用来启动一个 Binder 线程池,这样 SystemServer进程就可以使用 Binder与其他进程进行通信了。看到这里我们知道 Runtimelnit.java 的 nativeZygotelnit 函数主要是用来启动 Binder 线程池的。
2.3.1.2、进入 System Server 的 main 方法
我们再回到 Runtimelnit.j ava 的代码,在注释 2 处i周用了 Runtimelnit 的 applicationlnit方法 , 代码如下所示:
frameworks/base/core/java/com/android/internal/os/Runtimelnit.java
protected static void applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
...
invokeStaticMain(args.startClass, args.startArgs, classLoade r);
}
在 applicationlnit 方法中主要调用了 invokeStaticMain 方法:
frameworks/base/core/java/com/android/internal/os/Runtimelnit.java
private static void invokeStaticMain (String className, String[] argv, ClassLoader
classLoader)throws Zygote .MethodAndArgsCaller {
Class<?> cl;
try {
//通过反射得到 SystemServer 类
cl= Class.forName(className, true, classLoader);//l
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main" + className, ex);
}
Method m;
try {
//找到 SystemServer 的 main 方法
m = cl.get.Method("main", new Class[] {String[].class});//2
}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);
}
throw new Zygote.MethodAndArgsCaller(m, argv);//3
}
下面来查看在 Zygotelnit.java 的 main 方法中是如何捕获 MethodAndArgsCaller 异常的:
public static void main(Strinq argv[]) {
...
closeServerSocket ();
} catch (MethodAndArgsCaller caller) {
caller.run() ; // 1
}catch (RuntimeException ex){
Log.e(TAG, ” Zygote died with except 工 on ”, ex) ;
closeServerSocket() ;
throw ex;
}
}
当捕获到 MethodAndArgsCaller异常时就会在注释 l 处i周用 MethodAndArgsCaller 的 run方法, MethodAndArgsCaller 是 Zygote.java 的静态内部类:
frameworks/base/core/java/com/android/internal/os/Zygote.java
public static class MethodAndArgsCaller extends Exception implements Runnable {
private final Method mMethod;
private final String[] mArgs ;
public MethodAndArgsCaller(Method method , String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethosd.invoke(null, new Object[] { mArgs }) ;//1
}catch (IllegalAccessException ex) {
throw new RuntimeException(ex) ;
}
...
}
}
注释 1 处的 mMethod 指的就是 SystemServer 的 main 方法,调用了 mMethod 的 invoke方法后 , SystemServer 的 main 方法就会被动态调用, SystemServer 进程就进入了SystemServer 的 main 方法中 。
2.3.2、解析 SystemServer 进程
下面来查看 SystemServer 的 main 方法:
frameworks/base/services/java/com/android/server/SystemServer.java
public static void main (String[] args) {
new SystemServer() .run();
}
main 方注中只调用了 SystemServer 的 run 方法,如下所示:
frameworks/base/services/java/com/android/server/SystemServer.java
private void run () {
try {
...
//创建消息 Looper
Looper.prepareMainLooper() ;
//加载了动态库 libandroid servers.so
System.loadLibrary("android_servers"); //1
performPendingShutdown() ;
//创建系统的 Context
createSystemContext() ;
mSystemServiceManager = new SystemServiceManager(mSystemContext) ;//2
mSystemServiceMaηager.setRuntimeRestarted(mRuntimeRestart) ;
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager) ;
SystemServerInitThreadPool.get() ;
}finally {
traceEnd();
}
try {
traceBeginAndSlog("StartServices");
//启动引导服务
startBootstrapServices(); // 3
//启动核心服务
startCoreServices(); // 4
//启动其他服务
startOtherServices(); // 5
SystemServerInitThreadPool.shutdown();
}catch (Throwable ex) {
Slog.e("System","*************************************");
Slog.e("System","*******Failure starting system services", ex);
throw ex;
}finally {
traceEnd();
}
...
}
在 注 释 1 处加载了动态、 库 libandroid_servers.so。 接 下来在注释 2 处创 建SystemServiceManager , 它会对系统服务进行创建 、 启动和生命周期管理。在注释 3 处的startBootstrapServices 方 法 中用 SystemServiceManager 启动了 ActivityManagerService 、PowerManagerService 、 PackageManagerService 等服务 。 在注释 4 处的 startCoreServices 方法中则启动了DropBoxManagerService 、BatteryService 、UsageStatsService 和 Web ViewUpdateService 。在注释 5 处的 startOtherServices 方泣中启动了 CameraService 、 AlarmManagerService 、VrManagerService 等服务。这些服务的父类均为 System Service 。从注释 3 、 4 、 5 的方法中可以看出,官方把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务是一些非紧要和不需要立即启动的服务。这些系统服务总共有 100 多个,表 2- 1列出部分系统服务及其作用。
这些系统服务启动逻辑是相似的,这里以启动 PowerManagerService 来进行举例,代码如下所示:
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
SystemServiceManager 的 startService 方居启动了 PowerManagerService, startService 方法如下所示:
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public void startService(@NonNull final SystemService service) {
//注册 Service
mServices.add(service); //1
long time = System.currentTimeMillis();
try {
// 启动 Service
service.onStart(); //2
}catch (RuntimeException ex) {
throw new RuntimeException ("Failed to start service" + service.getClass().
getName() + ": onStart threw an exception", ex) ;
}
warnIfTooLong(System.currentTimeMillis() - time, service, "onStart");
}
在注释 1 处将 PowerManagerServ ice 添加到 mServices 中,其中 mServices 是一个存储SystemService 类型的 ArrayList ,这样就完成了 PowerManagerService 的注册工作 。在注释2 处调用 PowerManagerService 的 onStart 函数完成启动 PowerMan erService 。
除了用 mSystemServiceManager 的 startService 函数来启动系统服务外,也可以通过如下形式来启动系统服务,以 PackageManagerService 为例:
mPackageManagerService = PackageManagerService.main(mSystemContext,installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST OFF, mOnlyCore);
直接调用了 PackageManagerService 的 main 方法:
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public static PackageManagerService main(Context context , Installer installer ,
boolean factoryTest , boolean onlyCore) {
//自检初始的设置
PackageManagerServiceCompilerMapping.checkProperties();
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore); //1
m.enableSystemUserPackages();
ServiceManager.addService ("package", m);//2
return m;
}
在注释 1 处直接创建 PackageManagerService 并在注释 2 处将 PackageManagerService注册到 ServiceManager 中, ServiceManager 用来管理系统中的各种 Service ,用于系统 C/S架构中的 Binder 通信机制: Client 端要使用某个 Service ,则需要先到 ServiceManager 查询Service 的相关信息,然后根据 Service 的相关信息与 Service 所在的 Server 进程建立通信通
路,这样 Client 端就可以使用 Service 了。
2.3.3、SystemServer 进程总结
SystemServer 进程被创建后,主要做了如下工作:
- (1)启动 Binder 线程池,这样就可以与其他进程进行通信 。
- (2)创建 SystemServiceManager ,其用于对系统的服务进行创建、启动和生命周期管理。
- (3)启动各种系统服务。
2.4、Launcher 启动过程
此前已经学习了 Android 系统启动流程的 init 进程、 Zygote 进程和 SystemServer 进程,最后我们来学习 Launcher 的启动过程。
2.4.1、Launcher 概述
系统启动的最后一步是启动一个应用程序用来显示系统中已经安装的应用程序,这个应用程序就叫作 Launcher 。Launcher 在启动过程中会请求 PackageManagerService 返回系统中已经安装的应用程序的信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户可以通过点击这些快捷图标来启动相应的应用程序。
通俗来讲 Launcher 就是 Andro id 系统的桌面,它的作用主要有以下两点:
- (1)作为 Android 系统的启动器,用于启动应用程序 。
- (2)作为 Android 系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件。
2.4.2、Launcher 启动过程介绍
SystemServer 进程在启动的过程中会启动 PackageManagerService, PackageManagerService启动后会将系统中的应用程序安装完成。在此前已经启动的 AMS 会将 Launcher 启动起来。Launcher 启动过程的时序图如图 2 - 3 所示。
启动 Launcher 的入口为 AMS 的 systemReady 方法,他在 SystemServer 的 startOtherServices 方法中被调用,如下所示:
frameworks/base/services/java/com/android/server/SystemServer.java
private void sta rtOtherServices (){
...
mActivityManagerService.systemReady (() - > {//1
Slog.i(TAG, "Making services ready");
traceBeginAndSlog ("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
...
}
...
}
与 Android 7.1.2 源码不同的是, Android 8.0 的部分源码引入了 Java Lambda 表达式,比如注释 1 处。下面来查看 AMS 的 systernReady 方法做了什么:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback) {
...
synchronized(this){
...
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked (-1, currentUserid);
}
}
systernReady 方法中调用了 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked方法:
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord
target , ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked (target,
targetOptions); //1
}
...
return false;
}
在注释 1 处调用 ActivityStack 的 resumeTopActivityUncheckedLocked 方f去, ActivityStack对象是用来描述 Activity 堆栓的, resumeTopActivityUncheckedLocked 方住如下所示:
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptionsoptions) {
if (mStackSupervisor.inResumeTopActivity) {
return false ;
}
boolean result = false;
try {
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityinnerLocked(prev, options); //1
} finally {
mStackSupervisor.inResumeTopActivty = false;
}
mStackSupervisor.checkReadyForSleepLocked();
return result;
}
在注释 1 处i周用了 resumeTopActivitylnnerLocked 方法,如下所示 :
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions
options) {
...
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
...
}
resumeTopActivitylnnerLocked 方法的代码很长, 在此仅截取我们要分析的关键的部分 ,调用 ActivityStackSupervisor 的 resumeHomeStackTask 方法,代码如下所示:
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
...
if (r != null && !r.finishing) {
moveFocusableActivityStackToFrontLocked(r, myReason);
return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
}
return mService.startHomeActivityLocked(mCurrentUser, myReason);
}
在 resumeHomeStackTask 方法中调用了 AMS 的 startHomeActivityLocked 方法,如下所示:
frameworks/base/services/core/java/com/and raid/server/am/ActivityManagerService.java
boolean startHomeActivityLocked(int userid, String reason) {
//判断工厂模式和 mTopAction 的值,符合要求就继续执行下去
if (mFactoryTest = FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction = null) {//l
return false;
}
//创建 Launcher 启动所需的 Intent
Intent intent = geHomeintent(); //2
Activityinfo ainfo = resolveActivityinfo(intent, STOCK_PM_FLAGS, userld);
If (ainfo != null) {
Intent.setComponent(new ComponentName(ainfo.applicationInfo.packageName,
alnfo.name));
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) {//3
Intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserid = UserHandle.getUserid(
ainfo.applicationInfo.uid);
final String myReason = reason + ":" + userid + ":" + resolvedUserid;
//启动 Launcher
mActivityStarter.startHomeActivityLocked(intent, a!nfo, myReason);//4
}
}else {
Slog.wtf(TAG, "No home screen found for " + intent , new Throwable());
}
return true ;
}
注释 1 处的 mFactoryTest 代表系统的运行模式,系统的运行模式分为三种,分别是非工厂模式、低级工厂模式和高级工厂模式, mTopAction 则用来描述第一个被启动 Activity组件的 Action ,它的默认值为 Intent.ACTION_MAIN 。 因此注释 1 处的代码的意思就是mFactoryTest 为 FactoryTest.FACTORY_TEST_LOW_LEVEL (低级工厂模式)并且mTopAction 等于 null 时,直接返回 false 。 注释 2 处的 getHomelntent 方法如下所示:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
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;
}
在 getHomelntent 方法中创建了 Intent,并将 mTopAction 和 mTopData 传人。mTopAction的值为 Intent.ACTION_MAIN,并且如果系统运行模式不是低级工厂模式,则将 intent 的Category 设置为 Intent.CATEGORY HOME , 最 后返回 该 Intent ,再回到 AMS 的startHomeActivityLocked 方法,假设系统的运行模式不是低级工厂模式,在注释 3 处判断符合 Action 为 Intent.ACTION_MAIN 、 Category 可为 Intent.CATEGORY_HOME 的应用程序是否已经启动,如果没启动则i周用注释 4 处的方总启动该应用程序 。 这个被启动的应用程序就是 Launcher,因为 Launcher 的 AndroidManifest 文件中的 intent-filter 标签 匹配了 Action为 Intent.ACTION_MAIN, Category 为 Intent.CATEGORY_HOME 。
Launcher 的 AndroidManifest 文件如下所示:
packages/apps/Launcher3/AndroidManifest.xml
<manifest
xmlns:android = "http://schemas.android.com/apk/res/android"
package = "com.android.launcher3">
<uses-sdk android:targetSdkVersion = "23" android:minSdkVersion = "21" />
...
<application
...>
<activity
android:name = "com.android.launcher3.Launcher"
android:launchMode = "singleTask"
android:clearTaskOnLaunch = "true"
android:stateNotNeeded = "true"
android:windowSoftinputMode = "adjustPan | stateUnchanged"
android:screenOrientation = "nosensor"
android:configChanges = "keyboard | keyboardHidden | navigation"
android:resizeableActivity = "true"
android:resumeWhilePausing = "true"
android:taskAffinity=""
android:enabled = "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" />
</intent-filter>
</activity>
...
</application>
</manifest>
可以 看 到 intent-filter 设 置 了 android.intent.category.HOME 属 性 , 这样名称为com.android.launcher3 . Launcher 的 Activity 就成为了 主 Activity 。 从前面 AMS 的startHomeActivityLocked 方法的注释 4 处,我们得知如果 Launcher 没有启动就会调用
ActivityStarter 的 startHomeActivityLocked 方法来启动 Launcher ,如下所示:
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
void startHomeActivityLocked(Intent intent, ActivityInfo ainfo, String reason) {
// 将 Launcher 放入 HomeStack 中
mSupervisor.moveHomeStackTaskToTop(reas。n); //1
mLastHomeActivityStartResult = startActivityLocked (... );
}
在注释 1 处将 Launcher 放入 HomeStack 中, HomeStack 是在 ActivityStackSupervisor中定义的用于存储 Launcher 的变量 。接着调用 startActivityLocked 方怯来启动 Launcher,剩余的过程会和 Activity 的启动过程类似 , 本书将在第 4 章介绍该知识点 。最终进入Launcher 的 onCreate 方注中,到这里 Launcher 就完成了启动 。
2.4.3、Launcher 中应用图标显示过程
Launcher 完成启动后会做很多的工作,作为桌面它会显示应用程序图标, 这与应用程序开发有所关联,应用程序图标是用户进入应用程序的入口,因此我们有 必要了解Launcher 是如何显示应用程序图标的 。
我们先从 Launcher 的 onCreate 方法入手,代码如下所示 :
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
@Override
protected void onCreate(Bundle savedinstanceState) {
...
LauncherAppState app = LauncherAppState.getinstance(); //1
mDeviceProfile = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE ?
app.getinvariantDeviceProfile().landscapeProfile
: app.getinvariantDeviceProfile().portraitProfile;
mSharedPrefs = Utilities.getPrefs(this);
misSafeModeEnabled = getPackageManager().isSafeMode();
mModel = app.setLauncher(this); //2
...
if(!mRestoring) {
if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {
mModel.startLoader(PagedView.INVALID_RESTORE_PAGE); //3
}else{
mModel.startLoader(mWorkspace.getRestorePage());
}
}
...
}
在注释 1 处获取 LauncherAppState 的实例, 在注释 2 处调用它的 setLauncher 方法并将Launcher 对象传人, LauncherAppState 的 setLauncher 方法如下所示:
packages/apps/Launcher3/src/com/android/launcher3/LauncherAppState.java
LauncherModel setLauncher(Launcher launcher) {
getLocalProvider(mContext).setLauncherProviderChangeListener(launcher);
mModel.initialize(launcher);//l
return mModel;
}
在注释 1 处会调用 LauncherModel 的 initialize 方法:
packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java
publiC void initialize(Callbacks callbacks) {
synchronized (mLock) {
unbinditeminfosAndClearQueuedBindRunnables();
mCallbacks = new WeakReference<Callbacks>(callbacks);
}
}
在 initialize 方法中会将 Callbacks , 也就是传人的 Launcher,封装成一个弱 引用对象。因此我们得知 mCallbacks 变量指的就是封装成弱引用对象的 Launcher,这个 mCallbacks③后面会用到它。
再回到 Launcher 的 onCreate方法,在注释 3 处调用了 LauncherModel 的 startLoader 方法,如下所示 :
packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java
...
// 创建了具有消息循环的线程 HandlerThread 对象
@Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcherloader");//l
statiC {
sWorkerThread.start();
}
@Thunk static final Handler sWorker = new Handler (sWorkerThread.getooper());//2
...
public void startLoader(boolean isLaunching, int synchronousBindPage) {
synchronized (mLock) {
if (DEBUG_LOADERS) {
Log.d(TAG,"startLoader isLaunching = " + isLaunching);
}
mDeferredBindRunnables.clear();
if (mCallbacks != null && mCallbacks.get() != null) {
isLaunching = isLaunching || stopLoaderLocked();
mLoaderTask = new LoaderTask(mApp, isLaunching);//3
if (synchronousBindPage > - 1 && mAllAppsLoaded && mWorkspaceLoaded) {
mLoaderTask.runBindSynchronousPage(synchronousBindPage);
}else{
sWorkerThread.setPriority(Thread . NORM_PRIORITY) ;
sWorker.post(mLoaderTask);//4
}
}
}
}
在注释 1 处创建了具有消息循环的线程 HandlerThread对象。在注释 2 处创建了 Handler ,并且传入 HandlerThread 的 Looper,这里 Hander 的作用就是向 HandlerThread 发送消息。在注释 3 处创建 LoaderTask,在注释 4 处将 LoaderTask 作为消息发送给 HandlerThread。
LoaderTask 类实现了 Runnable 接口,当 LoaderTask 所描述的消息被处理肘,则会调用它的 run 方法, LoaderTask 是 LauncherModel 的内部类,代码如下所示 :
packages/apps/Launcher3/src/com/android/launcher3/LauncherModel .java
private class LoaderTask implements Runnable {
...
public void run() {
synchronized (mLock) {
if (mStopped) {
return;
}
misLoaderTaskRunning = true;
}
try {
if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");
misLoadingAndBindingWorkspace = true;
//加载工作区信息
loadWorkspace(); //1
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace");
//绑定工作区信息
bindWorkspace(mPageToBindFirst); //2
if (DEBUG_LOADERS) Log.d(TAG, "step 1 completed, wait for idle");
waitForidle();
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: load工ng all apps");
//加载系统已经安装的应用程序信息
LoadAllApps(); //3
...
}catch (CancellationException e) {
} finally {
...
}
}
}
Launcher 是用 工作区的形式来显示系统安装的应用程序的快捷图标的,每一个工作区都是用来描述一个抽象桌面的,它由 n 个屏幕组成, 每个屏幕又分为 n 个单元格,每个单元格用来显示一个应用程序的快捷图标。 在注释 1 处和注释 2 处分别调用 loadWorkspace方法和 bindWorkspace 方法来加载和绑定工作区信息。注释 3 处的 loadAllApps 方住用来加载系统已经安装的应用程序信息,代码如下所示 :
packages/apps/Launcher3/src/com/android/launcher3/LauncherModel .java
private void loadAllApps() {
...
mHandler.post(new Runnable () {
public void run() {
final long bindTime = SystemClock.uptimeMillis();
final Callbacks callbacks= tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.bindAllApplications(added);//1
if (DEBUG_LOADERS) {
Log.d(TAG, "bound " + added.size() + " apps in "
+ (SystemClock.uptimeMillis() - bindTime) + "ms");
}
}else{
Log.i(TAG, "not binding apps: no Launcher activity");
}
}
});
...
}
在注释 1 处会调用 callbacks 的 bindAllApplications 方法 ,从之前的标注③处我们得知这个 callbacks 实际是指向 Launcher的 , 下面我们来查看 Launcher 的 bindA!!Applications方法 :
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
public void bindAllApplications(final ArrayList<Appinfo> apps) {
if ( waitUntilResume(mBindAllApplicationsRunnable, true)) {
mTmpAppsList = apps;
return;
}
if (mAppsView != null) {
mAppsView.setApps(apps); //1
}
if (mLauncherCallbacks != null) {
mLauncherCallbacks.bindAllApplications(apps);
}
}
在注释 1 处会i周用 Al!AppsContainerView 类型的 mAppsView 对象的 setApps 方法,井将包含应用信息的列表 apps 传进去, Al!AppsContainerView 的 setApps 方住如下所示 :
packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java
public void setApps(List<Appinfo> apps) {
mApps.setApps(apps);
}
setApps 方法会将包含应用信息的列表apps设置给mApps ,这个 mApps 是 Alphabetica!AppsList 类型的对象 。接着查看 Al!AppsContainerView 的 onFinishlnflate 方法如下所示 :
packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java
@Override
protected void onFinishinflate() {
super.onFinishinflate();
...
mAppsRecyclerView = (AllAppsRecyclerView)findViewByid(R.id.apps_list_view); //l
mAppsRecyclerView.setApps(mApps); //2
mAppsRecyclerView.setLayoutManager(mLayoutManager);
mAppsRecyclerView.setAdapter(mAdapter); //3
..
}
onFinishlnflate 方法会在 Al!AppsContainerView 加载完 XML 布局时调用, 在注释 1 处得到 AllAppsRecyclerView 用来显示 App 列表,井在注释 2 处将此前的 mApps 设置进去 ,在注释 3 处为 AllAppsRecyclerView 设置 Adapter。这样显示应用程序快捷图标的列表就会显示在屏幕上。
到这里 Launcher 中应用图标显示过程以及 Launcher 启动流程就讲解完了,接下来介绍Android 系统启动流程。
2.5、Android 系统启动流程
结合本章前 4 节的内容,我们可以清晰地总结出 Android 系统启动流程,这个流程主要有以下几个部分。
1、启动电源以及系统启动
当电源按下时引导芯片代码从预定义的地方(固化在 ROM )开始执行。加载引导程序BootLoader 到 RAM ,然后执行。
2、引导程序 Bootloader
引导程序 BootLoader 是在 Android 操作系统开始运行前的一个小程序,它的主要作用是把系统 OS 拉起来并运行。
3、Linux 内核启动
当内核启动时 ,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置时,它首先在系统文件中寻找 init.rc 文件,并启动 init 进程 。
4、init 进程启动
初始化和启动属性服务,井且启动 Zygote 进程。
5、Zygote 进程启动
创 建 Java 虚拟机井为 Java 虚拟机注册 JNI 方告,创建服务器端 Socket ,启动SystemServer 进程。
6、SystemServer 进程启动
启动 B inder 线程池和 SystemServiceManager,并且启动各种系统服务。
7、Launcher 启动
被 SystemServer 进程启动的 AMS 会启动 Launcher, Launcher 启动后会将己安装应用的快捷图标显示到界面上。
结合上面的流程,给出 Android 系统启动流程图 ,如图 2-4 所示 。
实际上 Android 系统启动流程要比图 2-4 复杂得多 ,这里只是为了便于理解简化了很多细节。对于 Android 应用开发来说,这些知识点已经足够了。
2.6、本章小节
为了更好地理解 Android 系统启动流程,本章中我们先后学习了 init 进程启动过程、Zygote 进程启动过程、 SystemServer 进程处理过程和 Launcher 启动过程,这些进程的启动过程其实细节很多也很复杂, 而本章更注重流程 ,因此并不会对每一个细节进行深挖,如果想要深拉就需要读者自行阅读源码。另外,本章所讲到的知识会和后面章节有所关联,是全书的基础章节。