相關(guān)文章鏈接:
1. Android Framework - 學(xué)習(xí)啟動篇
2. Android 系統(tǒng)服務(wù) - AMS 的啟動過程
3. Android 系統(tǒng)服務(wù) - PMS 的啟動過程
4. Android Framework - 開機(jī)啟動 Zygote 進(jìn)程
相關(guān)源碼文件:
/frameworks/base/services/core/java/android/os/Process.java
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
/frameworks/base/core/java/android/app/ActivityThread.java
/frameworks/base/core/java/android/app/LoadedApk.java
1. AMS 與 Zygote 通信過程
無論是點(diǎn)擊桌面圖標(biāo)調(diào)用 startActivitySafely 還是直接調(diào)用 startActivity 在源碼中都是調(diào)用的 startActivityForResult 方法。由于 Activity 的啟動流程有些復(fù)雜,因此本文先從進(jìn)程的 fork 創(chuàng)建過程來入手分析。
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's process already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
// 判斷進(jìn)程是否創(chuàng)建
if (app != null && app.thread != null) {
...
}
// 當(dāng)前進(jìn)程沒有創(chuàng)建則先創(chuàng)建進(jìn)程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
try {
// 設(shè)置參數(shù)
...
// 設(shè)置 entryPoint = "android.app.ActivityThread"
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
// 啟動創(chuàng)建進(jìn)程
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
synchronized (mPidsSelfLocked) {
// 緩存 pid 和 進(jìn)程信息
this.mPidsSelfLocked.put(startResult.pid, app);
...
}
...
} catch (RuntimeException e) {
...
}
}
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
ArrayList<String> argsForZygote = new ArrayList<String>();
// 添加創(chuàng)建進(jìn)程的基本參數(shù)
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
...
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
...
// 向 zygote 發(fā)起創(chuàng)建進(jìn)程的請求,通過 socket 的方式
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
// 打開 zygot socket 連接
private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
}
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
// The primary zygote didn't match. Try the secondary.
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
}
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
private static ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
// 獲取 socket 的 output 與 input
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
// 把數(shù)據(jù)傳送給 zygote 進(jìn)程
writer.write(Integer.toString(args.size()));
writer.newLine();
int sz = args.size();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
if (arg.indexOf('\n') >= 0) {
throw new ZygoteStartFailedEx(
"embedded newlines not allowed");
}
writer.write(arg);
writer.newLine();
}
writer.flush();
// 處理 zygote fork 進(jìn)程返回的結(jié)果
ProcessStartResult result = new ProcessStartResult();
result.pid = inputStream.readInt();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
result.usingWrapper = inputStream.readBoolean();
return result;
} catch (IOException ex) {
// 有異常則關(guān)閉連接
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
activity 的啟動過程中會掉用 startSpecificActivityLocked 方法,首先會根據(jù) processName 和 uid 來判斷進(jìn)程是否有創(chuàng)建,如果沒有創(chuàng)建進(jìn)程則需要先創(chuàng)建進(jìn)程,processName 默認(rèn)情況是包名,uid 是由 PMS 在啟動的過程中解析計(jì)算好的,其具體的計(jì)算賦值過程可以參考《Android 系統(tǒng)服務(wù) - PMS 的啟動過程》
如果當(dāng)前進(jìn)程沒有創(chuàng)建,則調(diào)用 Process 的 startViaZygote 方法去創(chuàng)建進(jìn)程,就是向 Zygote 進(jìn)程發(fā)起創(chuàng)建進(jìn)程的請求,這里跨進(jìn)程通信采用的是 Socket 套接字的方式。注意,其中有一個重要的參數(shù) entryPoint 是 android.app.ActivityThread 。
2. Zygote fork 創(chuàng)建進(jìn)程
// 循環(huán)讀取處理請求
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
try {
// 讀取 AMS 發(fā)過來的參數(shù)
args = readArgumentList();
} catch (IOException ex) {
...
return true;
}
try {
parsedArgs = new Arguments(args);
// fork 創(chuàng)建進(jìn)程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
} catch (ErrnoException ex) {
...
}
try {
if (pid == 0) {
// child process 處理
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
return true;
} else {
// parent process 處理
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
String instructionSet, String appDataDir) {
int pid = nativeForkAndSpecialize(
uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
instructionSet, appDataDir);
...
return pid;
}
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint debug_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jstring instructionSet, jstring dataDir) {
// 調(diào)用系統(tǒng)函數(shù) fork
pid_t pid = fork();
...
return pid;
}
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
// 關(guān)閉 zygote 進(jìn)程繼承過來的 socket 連接
closeSocket();
ZygoteInit.closeServerSocket();
...
if (parsedArgs.invokeWith != null) {
...
} else {
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
// common 初始化
commonInit();
// 初始化打開 binder 驅(qū)動
nativeZygoteInit();
// 拋異常,然后執(zhí)行 ActivityThread.main 方法
applicationInit(targetSdkVersion, argv, classLoader);
}
Zygote 啟動后會循環(huán)處理客戶端發(fā)過來的請求,當(dāng)接收到請求后會調(diào)用 ZygoteConnection 的 runOnce 方法,解析到客戶端的參數(shù)后會調(diào)用 native 底層的 fork 的方法,至此進(jìn)程才真正創(chuàng)建完畢。進(jìn)程 fork 完畢后,Zygote 進(jìn)程會將信息返回給 AMS,新創(chuàng)建的進(jìn)程會調(diào)用 commonInit 、nativeZygoteInit 和 applicationInit 三個核心方法:
- commonInit:通用初始化方法
- nativeZygoteInit:打開底層 binder 驅(qū)動
- applicationInit:調(diào)用 ActivityThread 的 main 方法
3. Application 的創(chuàng)建與綁定
public static void main(String[] args) {
// 創(chuàng)建主線程 Looper
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
// 進(jìn)入 loop 循環(huán)
Looper.loop();
}
private void attach(boolean system) {
if (!system) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
// 像 AMS 發(fā)起綁定請求
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
...
} else {
...
}
}
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// 通過 pid 查詢到進(jìn)程信息,之前 fork 后有緩存
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
...
// 綁定 thread
app.makeActive(thread, mProcessStats);
...
try {
// 回調(diào) bindApplication 方法
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
} catch (Exception e) {
...
return false;
}
return true;
}
private void handleBindApplication(AppBindData data) {
try {
// 創(chuàng)建綁定 Application
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
// 查找到 application 的 class
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
// 默認(rèn)是 android.app.Application
appClass = "android.app.Application";
}
try {
// 先創(chuàng)建 ClassLoader
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
// 創(chuàng)建一個 ContextImpl
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 創(chuàng)建和綁定 Application
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
// 調(diào)用 Application 的 onCreate 方法
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
...
return app;
}
// 創(chuàng)建 application 并且調(diào)用 attach 方法
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
進(jìn)程 fork 后會執(zhí)行 ActivityThread 的 main 方法,該方法又會向 AMS 發(fā)起綁定 IApplicationThread 請求,這里 IApplicationThread 是一個可以跨進(jìn)程通信的 Binder 對象,然后 AMS 又會調(diào)用 IApplicationThread 的 bindApplication 方法去創(chuàng)建應(yīng)用的 Application,等應(yīng)用的 Application 創(chuàng)建完畢后,才會真正的開始創(chuàng)建啟動 Activity 。
視頻地址:https://pan.baidu.com/s/1tB9hDc_6Aw_L0pgtbAU8Sw
視頻密碼:6fzw