1. 启动ActivityManagerService
在前面第14章讲到,在System进程启动时,会启动系统的一些基本服务。启动就有ActivityManagerService和PackageManagerService。在SystemServer中如下启动ActivityManagerService。
frameworks/base/services/java/com/android/server/SystemServer.java :
startService就是创建了ActivityManagerService的实例对象mActivityManagerService,然后启动了ActivityManagerService的looper线程。在SystemServer启动了基本服务后,就会调用mActivityManagerService的systemReady函数来启动HomeActivity。
2. 启动HomeActivity
目前仍在SystemServer主线程中调用的systemReady函数。该函数又会接着调用startHomeActivityLocked函数来启动HomeActivity,具体如下:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java :
这里交给了mStackSupervisor.startHomeActivity函数来启动HomeActivity,然后就会调用startActivityLocked函数。到这里,就开始重复第2章中,启动普通应用的activity的过程了,不再赘述。其中,在Launcher的Manifest中指明了它的类型为android.intent.category.home,所以启动的就是Laucher应用。
3. Launcher展示应用
下面从Launcher的onCreate函数开始讲起,部分代码如下:
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java :
其中mModel是一个LauncherModel对象,它负责加载应用信息。在重载的startLoader函数中:
|
|
因为加载所有安装的应用信息是一个比较耗时的过程,所以应该交给一个异步线程来处理。这里先创建了一个加载任务mLoaderTask,然后将它交给sWorkerThread来处理。sWorkerThread是一个HandlerThread,我们知道HandlerThread是一个独立的线程,并且有着自己的looper。mLoaderTask加载任务执行一次就可以结束,但是为什么需要用一个HandlerThread在这里不断等待着其它任务呢?因为桌面上应用可以动态的添加和删除,所以应用的加载可能是频繁的。这里使用HandlerThread可以避免重复的创建加载线程。
下面我们就看LoaderTask.run函数中具体做了哪些任务。
packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java :
WorkSpace就是Android桌面中的分屏,每个分屏有若干应用。先加载工作区,再加载应用更符合用户的心理预期?函数loadAndBindAllApps会判断是否已经加载过应用,如果已经加载过信息,则直接将app显示在桌面上即可;如果没有,则需要先调用函数loadAllApps,具体内容如下:
packages/apps/Launcher3/src/com/android/luancher3/LauncherModel.java :
mLauncherApps.getActivityList获取app信息的方法是通过向PackageManager发送请求的方式实现的。下面回到Launcher主线程,开始显示应用图标。首先看一眼这个回调函数:
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java :
mAppsView是一个view的容器,维持了一个AlphabeticalAppsList列表,保存应用的信息。当向其中添加新的应用信息后,会对home上的应用进行更新。当home上的图标被点击后,会触发启动该应用。