frameworks 之FallbackHome
- FallbackHome 启动
- 启动 Activity 流程
- 创建进程
- ActivityThrad 与 AMS
- 启动真正的 Launcher
mActivityManagerService 创建后会启动 FallbackHome 再启动桌面程序。因为此时还没解锁,桌面又涉及很多其他应用程序相关,所以要等待用户解锁后才能启动桌面程序,这就是为啥屏幕解锁后只有壁纸 等待一下才看到桌面。
涉及到的类如下
- frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
- frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
- frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
- frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
- frameworks/base/services/core/java/com/android/server/wm/Task.java
- frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
- frameworks/base/services/core/java/com/android/server/am/ProcessList.java
- frameworks/base/core/java/android/os/Process.java
- frameworks/base/core/java/android/os/ZygoteProcess.java
- frameworks/base/core/java/android/app/ActivityThread.java
- frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
- packages/apps/Settings/src/com/android/settings/FallbackHome.java
FallbackHome 启动
systemService 启动 activityMangerService 后 会在 systemReady 方法中 启动对应的 fallbackHome , 其中mAtmInternal 为 ActivityTaskManagerService
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
...
// Enable home activity for system user, so that the system can always boot. We don't
// do this when the system user is not setup since the setup wizard should be the one
// to handle home activity in this case.
if (UserManager.isSplitSystemUser() &&
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0) != 0
|| SystemProperties.getBoolean(SYSTEM_USER_HOME_NEEDED, false)) {
t.traceBegin("enableHomeActivity");
ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
try {
AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
t.traceEnd();
}
// 启动
if (bootingSystemUser) {
t.traceBegin("startHomeOnAllDisplays");
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
t.traceEnd();
}
}
startHomeOnAllDisplays 里面又直接调用了 RootWindowContainer 遍历每个屏幕 启动对应的 startHomeOnDisplay 方法 ,接着又调用 startHomeOnDisplay 方法。观察该方法 我们可以发现里面的 startHomeOnTaskDisplayArea 方法 大概就是启动对应的 fallbackhome。
// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean startHomeOnAllDisplays(int userId, String reason) {
boolean homeStarted = false;
for (int i = getChildCount() - 1; i >= 0; i--) {
final int displayId = getChildAt(i).mDisplayId;
homeStarted |= startHomeOnDisplay(userId, reason, displayId);
}
return homeStarted;
}
// 启动
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
// Fallback to top focused display or default display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
final Task rootTask = getTopDisplayFocusedRootTask();
displayId = rootTask != null ? rootTask.getDisplayId() : DEFAULT_DISPLAY;
}
final DisplayContent display = getDisplayContent(displayId);
// 其中的 startHomeOnTaskDisplayArea 启动对应的 fallbackHome
return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) ->
result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
allowInstrumenting, fromHomeKey),
false /* initValue */);
}
进入 startHomeOnTaskDisplayArea 可以看到 先获取对应的 homeIntent 因为还没解锁 所以获取不到 Launcher 要是解锁后 因为Launcher优先级比较高 就会变为获取到 Launcher 其中 intent 为 public static final String CATEGORY_HOME = “android.intent.category.HOME”;
找到 对应的 intent 后 进入 startHomeActivity
boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
boolean allowInstrumenting, boolean fromHomeKey) {
...
// 获取 intent
ActivityInfo aInfo = null;
if (taskDisplayArea == getDefaultTaskDisplayArea()) {
homeIntent = mService.getHomeIntent();
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
aInfo = info.first;
homeIntent = info.second;
}
...
// 启动 activity
// Update the reason for ANR debugging to verify if the user activity is the one that
// actually launched.
final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
taskDisplayArea);
}
进入后 会看到 obtainStarter 进入对应的 设置对应的 参数后 ,执行 execute 启动actiity
// frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
TaskDisplayArea taskDisplayArea) {
...
// 进入启动的流程,设置对应的 参数后 ,执行 execute 启动actiity
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();
}
进入 ActivityStarter , 执行对应的 execute 方法。 execute方法前面是拼接参数。最终执行启动是 executeRequest
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
...
res = executeRequest(mRequest);
}
启动 Activity 流程
进入 流程 IApplicationThread 作为 对应 应用的 ActivityThread 和应用通信的 Ibinder 还没创建 所以为空。 创建对应的 ActivityRecord 后执行 startActivityUnchecked,注意传入该 onResume 参数为 true 调用该 方法后,又会调用 厘米的 startActivityInner 。
...
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int executeRequest(Request request) {
final ActivityRecord r = new ActivityRecord.Builder(mService)
...
// 执行启动,注意传入该 onResume 参数为 true
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask, inTaskFragment, restrictedBgActivity, intentGrants);
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
mService.deferWindowLayout();
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
// 启动
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
intentGrants);
startResultSuccessful = ActivityManager.isStartResultSuccessful(result);
}
因为 前面传入的 onResume 为 true ,所以进入该方法后,会执行 resumeFocusedTasksTopActivities 。
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
...
// 为 true 进入该方法 最终调用 resumeFocusedTasksTopActivities
if (mDoResume) {
...
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
}
}
接着里面调用 task 的 resumeTopActivityUncheckedLocked 。
// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
...
boolean result = false;
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) {
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
}
}
调用 resumeTopActivityInnerLocked, 调用后 里面又会继续调用 resumeTopActivity 方法。
// frameworks/base/services/core/java/com/android/server/wm/Task.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...
if (isLeafTask()) {
if (isFocusableAndVisible()) {
someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
}
}
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...
final TaskFragment topFragment = topActivity.getTaskFragment();
resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
}
resumeTop 因为 还没创建对应的进程 所以 next.attachedToProcess() 为 false , 进入 else 判断, 会执行 startSpecificActivity
// frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (next.attachedToProcess()) {
...
} else {
// 创建对应的进程
mTaskSupervisor.startSpecificActivity(next, true, true);
}
}
执行 ActivityTaskSupervisor 里面 判断是否进程存在,不存在 执行调用 startProcessAsync 创建进程,存在则调用 realStartActivityLocked
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
//1.如果wpc不为null且hasThread表示应用Activity所属进程存在,直接realStartActivityLocked启动Activity
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}
// 创建进程
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
创建进程
PooledLambda.obtainMessage() 获取一个 Message,并为其指定 Callback,message 在判断到有 callback 参数时候 会执行 run 方法。 即执行 mService.mAmInternal 对象的 ActivityManagerInternal::startProcess 函数,函数入参为 r.processName、r.info.applicationInfo 等5个参数。由此可知,ActivityManagerInternal 的 startProcess() 方法是请求启动应用进程的起点.
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
}
我们之前说过 mAmInternal 的实现类为 ActivityManagerService, 查看 startProcess 方法。里面调用 startProcessLocked 方法。里面在调用 startProcessLocked
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
...
// 启动进程 isolated 传入参数为 false
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */);
}
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
boolean isolated) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
接着调用 ProcessList 里面的 他会先判断 app 即 ProcessRecord 是否为空。如果为空 创建对应的对象,然后调用 startProcessLocked 接着创建,, 里面又会接着调用 startProcessLocked
// frameworks/base/services/core/java/com/android/server/am/ProcessList.java
ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
if (app == null) {
checkSlow(startTime, "startProcess: creating new process record");
app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
...
} else {
...
}
// 创建进程
final boolean success =
startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
}
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, String abiOverride) {
return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
abiOverride);
}
startProcessLocked 里面又对 app 属性进行赋值,最终在调用 startProcessLocked, 里面接着调用 startProcess 方法 , 其中 entryPoint 为 android.app.ActivityThread。 这就是 应用程序 启动会 走 ActivityThread 入口。
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
String abiOverride) {
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
// 创建进程时候,入口
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);
}
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
// 创建进程
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
requiredAbi, instructionSet, invokeWith, startTime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
}
startProcess 方法 会对各种情况做判断,启动 fallbackHome 是走 Process.start。
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
int mountExternal, String seInfo, String requiredAbi, String instructionSet,
String invokeWith, long startTime) {
// 启动webview的
if (hostingRecord.usesWebviewZygote()) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
app.getDisabledCompatChanges(),
new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
} else if (hostingRecord.usesAppZygote()) {
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
// We can't isolate app data and storage data as parent zygote already did that.
startResult = appZygote.getProcess().start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap,
false, false,
new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
} else {
// 应用启动
regularZygote = true;
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,
allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
}
}
而progress start方法 里面实际又是调用 ZygoteProcess 的 start 方法 。 zygoteProcess 里面又调用 startViaZygote 方法。 该方法里面会对 创建的一些参数 进行初始化。其中 之前传入的 entryPoint 作为参数 放到最后。根据之前的文章 知道会解析 – 的参数,把没有的参数 放到remaind 参数里面 反射调用 启动main 方法。
// frameworks/base/core/java/android/os/ZygoteProcess.java
public final Process.ProcessStartResult start(@NonNull final String processClass,....){
....
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,
bindMountAppStorageDirs, zygoteArgs);
}
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass ...){
..
// 初始化参数
ArrayList<String> argsForZygote = new ArrayList<>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
...
// 最后要反射的参数
argsForZygote.add(processClass);
if (extraArgs != null) {
Collections.addAll(argsForZygote, extraArgs);
}
synchronized(mLock) {
// The USAP pool can not be used if the application will not use the systems graphics
// driver. If that driver is requested use the Zygote application start path.
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags,
argsForZygote);
}
}
zygoteSendArgsAndGetResult 接着调用 attemptZygoteSendArgsAndGetResult ,将参数拼接为 string 字符串, 该方法通过 socket 将消息 发送给 zygote 创建进程。
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
...
if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {
try {
return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
} catch (IOException ex) {
// If there was an IOException using the USAP pool we will log the error and
// attempt to start the process through the Zygote.
Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
+ ex.getMessage());
}
}
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
// 发送对应 socket
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
zygoteWriter.write(msgStr);
zygoteWriter.flush();
// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
Process.ProcessStartResult result = new Process.ProcessStartResult();
// 读取返回创建的pid
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
}
发送 socket 对应的 参数 zygoteWriter 是在 ZygoteState 初始化的时候, 传入 。
而该参数又是通过 connect 方法的时候 。创建 LocalSocket。 创建socket。并建立连接。 创建该 socket 传入的地址 为 LocalSocketAddress zygoteSocketAddress 参数。该参数又是在 ZygoteProcess 初始化的时候 创建 对应字符串 为 zygote 。
// frameworks/base/core/java/com/android/internal/os/Zygote.java
/**
* @hide for internal use only.
*/
public static final String PRIMARY_SOCKET_NAME = "zygote";
/**
* @hide for internal use only.
*/
public static final String SECONDARY_SOCKET_NAME = "zygote_secondary";
// frameworks/base/core/java/android/os/ZygoteProcess.java
public ZygoteProcess() {
mZygoteSocketAddress =
new LocalSocketAddress(Zygote.PRIMARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
mZygoteSecondarySocketAddress =
new LocalSocketAddress(Zygote.SECONDARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
mUsapPoolSocketAddress =
new LocalSocketAddress(Zygote.USAP_POOL_PRIMARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
mUsapPoolSecondarySocketAddress =
new LocalSocketAddress(Zygote.USAP_POOL_SECONDARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
// This constructor is used to create the primary and secondary Zygotes, which can support
// Unspecialized App Process Pools.
mUsapPoolSupported = true;
}
这样就把消息 发给了 zygote 那边。之前的文章 ZygoteInit 执行 main 函数后,会执行 zygoteServer.runSelectLoop(abiList); 方法 里面为 死循环 一直等待新消息 唤醒。收到消息后 执行 processCommand
if (pollIndex == 0) {
// Zygote server socket
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
// Session socket accepted from the Zygote server socket
try {
ZygoteConnection connection = peers.get(pollIndex);
boolean multipleForksOK = !isUsapPoolEnabled()
&& ZygoteHooks.isIndefiniteThreadSuspensionSafe();
final Runnable command =
connection.processCommand(this, multipleForksOK);
}
processCommand 方法方法里面 又是我们熟悉的 fork 进程 Zygote.forkAndSpecialize
fork 出进程后 调用 handleChildProc 方法处理进程 。处理应用程序进程:将 ActivityThread 的 main() 方法封装到 Runnable 中
因为 非zygote 进程,所以 执行 ZygoteInit.zygoteInit 。 说明:ZygoteInit.nativeZygoteInit() 启动了 Binder 线程池,应用程序进程此后可以通过 Binder 实现跨进程通讯。RuntimeInit.applicationInit 里面通过调用 findStaticMain 基于反射创建 ActivityThread 。 并返回 runable。 最终会返回给 ZygoteInit 的 main() 方法执行其 run() 方法
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
...
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(
parsedArgs.mRemainingArgs /* classLoader */);
}
}
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
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();
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
这样就调用到 ActivityThrad main 方法。
ActivityThrad 与 AMS
进入 ActivityThrad 方法,里面包含对 Looper 的创建。创建 ActivityThread 因为非系统进程 所以 attach 传入为 false 。 loop 开启 循环
public static void main(String[] args) {
// looper跟当前线程创建
Looper.prepareMainLooper();
// 创建 ActivityThread
ActivityThread thread = new ActivityThread();
...
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
//创建主线程 H 类:return mH, mH 在定义时就被初始化:final H mH = new H()
sMainThreadHandler = thread.getHandler();
}
...
//开启消息循环
Looper.loop();
}
查看 attach 方法 因为传入为 false 。所以第一个分支。其中 mgr 为 AMS 的binder对象。这样调用 attachApplication 将当前 app 进程的 ibinder对象传给AMS 这样 AMS 就可以调用我们进程的方法
// frameworks/base/core/java/android/app/ActivityThread.java
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) { //system = false
...
//mAppThread 为 ApplicationThread 类型,在定义时就被初始化
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//获取 AMS
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
}
...
}
...
}
IActivityManger 也是通过 ServiceManger 获取, IActivityManger 的实现 为 ActivityManagerService。
// frameworks/base/core/java/android/app/ActivityManager.java
// 获取单例
private static IActivityTaskManager getTaskService() {
return ActivityTaskManager.getService();
}
@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
查看 ActivityManagerService 里面的 attachApplication 方法,获取了调用的pid 后,接着又调用了 attachApplicationLocked 方法。里面通过 bindApplication 调用 Applicaiton的 onCreate 方法。getCommonServicesLocked() 方法中将 WMS、DMS、IMS、PMS 等服务的 name 和 binder 添加到 mAppBindArgs(类型:ArrayMap<String, IBinder>)中,并将其返回。这样我们在Activity 中就可以通过context 获取。 最后在调用 mAtmInternal.attachApplication 该方法会调用获取对应 入口activity。
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// 绑定AIDL监听
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.setDeathRecipient(adr);
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
mProcessList.startProcessLocked(app,
new HostingRecord("link fail", processName),
ZYGOTE_POLICY_FLAG_EMPTY);
return false;
}
...
// 走else 的 bindApplication 调用 Applicaiton的 onCreate 方法。
if (app.isolatedEntryPoint != null) {
...
} else if (instr2 != null) {
thread.bindApplication(processName, appInfo, providers, instr2.mClass, profilerInfo, instr2.mArguments,
instr2.mWatcher, instr2.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled,
enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()), app.compat,
getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions, app.mDisabledCompatChanges);
} else {
//第 4 个参数为 ComponentName 类型,影响 Instrumentation 的创建方式
thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode,
app.isPersistent(), new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions, app.mDisabledCompatChanges);
}
...
app.makeActive(thread, mProcessStats);
// See if the top visible activity is waiting to run in this process...
// 启动对应的launch Activity
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
...
// Find any services that should be running in this process...
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
}
查看 ActivityThrad 里面的 BindApplication 方法。通过将传回来的服务,放到 ServiceManger 里面。 在发送 消息 到 BIND_APPLICATION
public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers,
ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection,
int debugMode, boolean enableBinderTracking, boolean trackAllocation, boolean isRestrictedBackupMode,
boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions, ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
if (services != null) {
...
// sCache.putAll(services), sCache 为 Map<String, IBinder> 类型
ServiceManager.initServiceCache(services);
}
//relaunchAllActivities(false)
setCoreSettings(coreSettings);
AppBindData data = new AppBindData();
...
data.instrumentationName = instrumentationName;
...
//ActivityThread 的内部类 H 类处理消息,将业务从 Binder 线程切换至主线程
sendMessage(H.BIND_APPLICATION, data);
收到消息后 执行了 handleBindApplication 方法。对JVM和堆栈进行设置。设置 UI线程为重要线程。对时间 语言 等进行设置。 **创建 Instrumentation (控制activity的生命周期)**并 通过 createAppContext 创建上下文。最后调用 mInstrumentation.callApplicationOnCreate(app); 执行 Application 的 onCreate 。
private void handleBindApplication(AppBindData data) {
// 将当前UI线程设置为最重要进程
// Register the UI Thread as a sensitive thread to the runtime.
VMRuntime.registerSensitiveThread();
// In the case the stack depth property exists, pass it down to the runtime.
// 设置当前调试的跟踪栈深度
String property = SystemProperties.get("debug.allocTracker.stackDepth");
if (property.length() != 0) {
VMDebug.setAllocTrackerStackDepth(Integer.parseInt(property));
}
if (data.trackAllocation) {
DdmVmInternal.setRecentAllocationsTrackingEnabled(true);
}
...
final InstrumentationInfo ii;
...
//创建 Application 的 Context
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
...
//ii 是否为 null,取决于 data.instrumentationName 是否为 null
if (ii != null) {
...
//创建 Instrumentation 的 Context,
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi, appContext.getOpPackageName());
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance();
}
...
//注入 ActivityThread、Context、ComponentName 等
mInstrumentation.init(this, instrContext, appContext, component, data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
...
} else {
mInstrumentation = new Instrumentation();
//注入 ActivityThread
mInstrumentation.basicInit(this);
}
...
Application app;
...
try {
//创建 Application 对象
app = data.info.makeApplication(data.restrictedBackupMode, null);
...
mInitialApplication = app;
...
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
...
try {
//调用 Application 的 onCreate() 方法
mInstrumentation.callApplicationOnCreate(app);
}
...
}
...
}
回到之前的 mAtmInternal.attachApplication 方法。该方法会启动对应的 activity,该方法具体实现为 ActivityTaskManagerService 。执行
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
}
try {
return mRootWindowContainer.attachApplication(wpc);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
}
attachApplication 方法又会调用 RootWindowContainer 的 startActivityForAttachedApplicationIfNeeded方法。继而调用 realStartActivityLocked 。
// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
final PooledFunction c = PooledLambda.obtainFunction(
RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
PooledLambda.__(ActivityRecord.class), app,
rootTask.topRunningActivity());
rootTask.forAllActivities(c);
}
private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
WindowProcessController app, ActivityRecord top) {
if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard || r.app != null
|| app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
return false;
}
try {
if (mTaskSupervisor.realStartActivityLocked(r, app,
top == r && r.getTask().canBeResumed(r) /*andResume*/,
true /*checkConfig*/)) {
mTmpBoolean = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ top.intent.getComponent().flattenToShortString(), e);
mTmpRemoteException = e;
return true;
}
return false;
}
realStartActivityLocked 里面又会执行 scheduleTransaction 该方法会通过调用 AIDL scheduleTransaction 在 ActivityThread 执行。
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
在ActivityThread 那边会发送 Handler 消息 ActivityThread.H.EXECUTE_TRANSACTION。该方法会执行 execute 方法,最终执行到 handleRelaunchActivity 方法启动l auncher 方法。这里有小技巧因为里面堆栈较多实现类。所以这里在 handleLaunchActivity 添加堆栈打印。然后启动模拟器 查看堆栈。可以看到 最终是通过 TransactionExecutor.execute -> TransactionExecutor.executeCallbacks -> ActivityTransactionItem.execute -> ActivityRelaunchItem.execute -> ActivityThread.handleRelaunchActivity 启动 FallbackHome 的 主Activity。
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
Slog.v(TAG, "handleLaunchActivity", new NullPointerException());
}
启动真正的 Launcher
拉起 FallbackHome 界面后,该Activity 位于 packages/apps/Settings/src/com/android/settings/FallbackHome.java,可以通过 过滤 android.intent.category.HOME 查找
activity 的 onCreate 方法 ,注册了解锁的广播监听。收到即调用 maybeFinish 方法。
protected void onCreate(Bundle savedInstanceState) {
// 设置壁纸
mWallManager = getSystemService(WallpaperManager.class);
if (mWallManager == null) {
Log.w(TAG, "Wallpaper manager isn't ready, can't listen to color changes!");
} else {
loadWallpaperColors(flags);
}
// 注册解锁监听广播
registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
// 开始判断
maybeFinish();
}
该方法会 每隔 500毫秒 去获取 Intent.CATEGORY_HOME 的 activity 。并判断是否和当前包名一样,如果不一样则代表 已经检测到了 Launch 。结束自己并启动真正的 launch 。(因为解锁后就可以检测到 Launcher 而且优先级比 FallbackHome 高)
private void maybeFinish() {
if (getSystemService(UserManager.class).isUserUnlocked()) {
// 获取对应的 intent
final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME);
final ResolveInfo homeInfo = getPackageManager().resolveActivity(homeIntent, 0);
// 判断包名是否一致 ,一致延时500 毫秒 在检测
if (Objects.equals(getPackageName(), homeInfo.activityInfo.packageName)) {
Log.d(TAG, "User unlocked but no home; let's hope someone enables one soon?");
mHandler.sendEmptyMessageDelayed(0, 500);
} else {
Log.d(TAG, "User unlocked and real home found; let's go!");
getSystemService(PowerManager.class).userActivity(
SystemClock.uptimeMillis(), false);
finish();
}
}
}
// 延时任务检测
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
maybeFinish();
}
};
通过 PowerManger 的 userActivity 启动, 可以看到 最终 是调用了 IPowerManager , 查找 Context.POWER_SERVICE 看其注册地方。注册了 power ,对应的实现类为 PowerManagerService 。frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java