相關文章鏈接:
1. Android Framework - 學習啓動篇
2. Android 系統服務 - AMS 的啓動過程
3. Android 系統服務 - PMS 的啓動過程
4. Android Framework - 開機啓動 Zygote 進程
相關源碼文件:
/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 通信過程
無論是點擊桌面圖標調用 startActivitySafely 還是直接調用 startActivity 在源碼中都是調用的 startActivityForResult 方法。由於 Activity 的啓動流程有些複雜,因此本文先從進程的 fork 創建過程來入手分析。
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);
// 判斷進程是否創建
if (app != null && app.thread != null) {
...
}
// 當前進程沒有創建則先創建進程
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 {
// 設置參數
...
// 設置 entryPoint = "android.app.ActivityThread"
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
// 啓動創建進程
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 和 進程信息
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>();
// 添加創建進程的基本參數
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
...
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
...
// 向 zygote 發起創建進程的請求,通過 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;
// 把數據傳送給 zygote 進程
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 進程返回的結果
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) {
// 有異常則關閉連接
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
activity 的啓動過程中會掉用 startSpecificActivityLocked 方法,首先會根據 processName 和 uid 來判斷進程是否有創建,如果沒有創建進程則需要先創建進程,processName 默認情況是包名,uid 是由 PMS 在啓動的過程中解析計算好的,其具體的計算賦值過程可以參考《Android 系統服務 - PMS 的啓動過程》
如果當前進程沒有創建,則調用 Process 的 startViaZygote 方法去創建進程,就是向 Zygote 進程發起創建進程的請求,這裏跨進程通信採用的是 Socket 套接字的方式。注意,其中有一個重要的參數 entryPoint 是 android.app.ActivityThread 。
2. Zygote fork 創建進程
// 循環讀取處理請求
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 發過來的參數
args = readArgumentList();
} catch (IOException ex) {
...
return true;
}
try {
parsedArgs = new Arguments(args);
// fork 創建進程
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) {
// 調用系統函數 fork
pid_t pid = fork();
...
return pid;
}
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
// 關閉 zygote 進程繼承過來的 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 驅動
nativeZygoteInit();
// 拋異常,然後執行 ActivityThread.main 方法
applicationInit(targetSdkVersion, argv, classLoader);
}
Zygote 啓動後會循環處理客戶端發過來的請求,當接收到請求後會調用 ZygoteConnection 的 runOnce 方法,解析到客戶端的參數後會調用 native 底層的 fork 的方法,至此進程才真正創建完畢。進程 fork 完畢後,Zygote 進程會將信息返回給 AMS,新創建的進程會調用 commonInit 、nativeZygoteInit 和 applicationInit 三個核心方法:
- commonInit:通用初始化方法
- nativeZygoteInit:打開底層 binder 驅動
- applicationInit:調用 ActivityThread 的 main 方法
3. Application 的創建與綁定
public static void main(String[] args) {
// 創建主線程 Looper
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
// 進入 loop 循環
Looper.loop();
}
private void attach(boolean system) {
if (!system) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
// 像 AMS 發起綁定請求
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 查詢到進程信息,之前 fork 後有緩存
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
...
// 綁定 thread
app.makeActive(thread, mProcessStats);
...
try {
// 回調 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 {
// 創建綁定 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)) {
// 默認是 android.app.Application
appClass = "android.app.Application";
}
try {
// 先創建 ClassLoader
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
// 創建一個 ContextImpl
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 創建和綁定 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 {
// 調用 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;
}
// 創建 application 並且調用 attach 方法
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
進程 fork 後會執行 ActivityThread 的 main 方法,該方法又會向 AMS 發起綁定 IApplicationThread 請求,這裏 IApplicationThread 是一個可以跨進程通信的 Binder 對象,然後 AMS 又會調用 IApplicationThread 的 bindApplication 方法去創建應用的 Application,等應用的 Application 創建完畢後,纔會真正的開始創建啓動 Activity 。
視頻地址:https://pan.baidu.com/s/1tB9hDc_6Aw_L0pgtbAU8Sw
視頻密碼:6fzw