次部分承接上一篇文章https://blog.csdn.net/we1less/article/details/116139142?spm=1001.2014.3001.5501
registerServerSocket(socketName) AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
【1】 拼接socker名稱 ANDROID_SOCKET_zygote
String env = System.getenv(fullSocketName);
【2】得到socket的環境變數的值
mServerSocket = new LocalServerSocket(fd);
【3】創建服務器端socket并將檔案運算子作為引數傳遞進去 在zygote行程將systemserver行程啟動后就會在你這個服務器端的socket上等待AMS請求zygote行程來創建新的行程
關于socket這里附上一個文章https://www.cnblogs.com/zijianlu/archive/2013/04/18/3028090.html具體可以參考看看
preload(bootTimingsTraceLog) AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
...
preloadClasses();
...
preloadResources();
...
nativePreloadAppProcessHALs();
...
preloadOpenGL();
...
preloadSharedLibraries();
...
preloadTextResources();
...
warmUpJcaProviders();
...
}
【1】預加載位于/system/etc/preloaded-classes檔案中的類
【2】預加載drawble和color的資源資訊AOSP/frameworks/base/core/res/res/values/arrays.xml
drawble : preloaded_drawables
color : preloaded_color_state_lists
【3】通過JNI呼叫,預加載底層相關的資源
【4】預加載OpenGL資源
【5】預加載共享庫:"android","compiler_rt","jnigraphics"
【6】預加載文本連接符資源
【7】zygote中,記憶體共享行程
通過【1】【2】步驟的預加載可以使繼承自zygote的行程預加載系統檔案從而使得行程啟動更快
啟動systemserver AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
【1】forkSystemServer 父行程分支回傳null 子行程分支回傳 handleSystemServerProcess并回傳回去最終呼叫了run()方法 關于具體systemserver啟動會在后面單獨開一篇文章去分析到這里只需要知道啟動了systemserver就好
【2】Zygote.forkSystemServer 其內部會呼叫nativeForkSystemServer方法,這個native方法最侄訓通過fork()方法創建當前行程的一個子行程 對于fork()方法這里給出一篇文章有興趣的可以參考看看
https://www.cnblogs.com/coolgestar02/archive/2011/04/28/2032018.html 總之fork函式最終在父行程的回傳值是子行程的pid,而在子行程回傳的則是0
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
runSelectLoop(abiList) AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Zygote完成了Java的初始作業后,便呼叫runSelectLoop來讓自己無限回圈等待,如果收到子孫后臺的請求,它便會醒來為他們作業,
Runnable runSelectLoop(String abiList) {
...
fds.add(mServerSocket.getFileDescriptor());
...
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);
...
}
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 {
try {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
...
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(i);
fds.remove(i);
}
}
} catch (Exception e) {
...
}
}
}
}
}
【1】fds.add(mServerSocket.getFileDescriptor()); fds[0]為mServerSocket,即mServerSocket為位于zygote行程中的socket服務端
【2】Os.poll(pollFds, -1); 查詢輪訓狀態,當pollFdd有事件到來則往下執行,否則阻塞在這里
【3】if (i == 0) { ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); fds.add(newPeer.getFileDesciptor());
客戶端第一次請求服務端,服務端呼叫accept與客戶端建立連接,客戶端在zygote以ZygoteConnection物件表示
【4】else { try { ZygoteConnection connection = peers.get(i); final Runnable command = connection.processOneCommand(this);
經過上個if操作后,客戶端與服務端已經建立連接,并開始發送資料 peers.get(index) 取得發送資料客戶端的 ZygoteConnection 物件 然后呼叫 processOneCommand(this) 方法來出具具體請求
如果 i==0 表示說明服務端socket已經于客戶端連接上了 換句話說就是當前zygote行程已經于AMS連接上了
如果 i!=0 表示AMS向zygote行程發送一個創建應用行程的請求 再呼叫 processOneCommand(this) 方法fork出一個新的行程
【5】fds.remove(i); 處理完則從fds中移除該檔案描述符
processOneCommand() AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
在這里fork出一個子行程回傳handleChildProc 父行程執行handleParentProc
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/282330.html
標籤:其他
