本文的分析基于MTK提供的Android 7.0源码,并非Google官方提供的源码,其中可能有一些小的差异,还望谅解。
Launcher的本质就是一个普通应用,它比普通应用多配置了Category的Android:name=”android.intent.category.HOME”属性,之后ActivityManagerService的startHomeActivityLocked方法将启动含有这个属性的Activity。
boolean startHomeActivityLocked(int userId) {
if(this.mHeadless) {
this.ensureBootCompleted();
return false;
} else if(this.mFactoryTest == 1 && this.mTopAction == null) {
return false;
} else {
Intent intent = new Intent(this.mTopAction, this.mTopData != null?Uri.parse(this.mTopData):null);
intent.setComponent(this.mTopComponent);
if(this.mFactoryTest != 1) {
intent.addCategory("android.intent.category.HOME");
}
ActivityInfo aInfo = intent.resolveActivityInfo(this.mContext.getPackageManager(), 1024);
if(aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = this.getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = this.getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid);
if(app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | 268435456);
this.mMainStack.startActivityLocked((IApplicationThread)null, intent, (String)null, aInfo, (IBinder)null, (String)null, 0, 0, 0, 0, (Bundle)null, false, (ActivityRecord[])null);
}
}
return true;
}
}
这里贴出一篇关于ActivityManagerService启动Activity的博文:
http://blog.csdn.net/gaugamela/article/details/53183216
接下来看看Launcher界面的划分。Launcher3实质其实就是一个Activity包含N个自定义的View。
结合图和布局文件可能更好理解Launcher3的界面
<com.android.launcher3.LauncherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.android.launcher3.DragLayer
android:id="@+id/drag_layer"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.android.launcher3.FocusIndicatorView
android:id="@+id/focus_indicator"
android:layout_width="52dp"
android:layout_height="52dp" />
<!-- The workspace contains 5 screens of cells -->
<!-- DO NOT CHANGE THE ID -->
<com.android.launcher3.Workspace
android:id="@+id/workspace"
android:layout_width="match_parent"
android:layout_height="match_parent"
launcher:defaultScreen="@integer/config_workspaceDefaultScreen"
launcher:pageIndicator="@+id/page_indicator">
</com.android.launcher3.Workspace>
<!-- DO NOT CHANGE THE ID -->
<include layout="@layout/hotseat"
android:id="@+id/hotseat"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/overview_panel"
android:id="@+id/overview_panel"
android:visibility="gone" />
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->
<include
android:id="@+id/page_indicator"
layout=