android 28源码
一 启动Zygote进程
init进程 pid = 1 启动关键服务(ServiceManager、SurfaceFlinger等),守护关键服务
- 》ServiceManager
- 》zygote进程
- 》SystemServer
- 》 各个app进程
1 native层
/framework/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]) {
.......
if (zygote) {
//如果运行在zygote进程中则通过runtim开始启动进程。启动jvm,执行ZygoteInit.main()
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
// 其他的更具classname来执行进程。
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
2 java层
Zygote启动步骤:
1 加载系统class、资源等(子进程进程共享)
2 准备SocketServer(为启动app进程做准备)
3 启动SystemServer进程
4 等待连接,fork子进程,初始化子进程,进入子进程入口。
ZygoteInit.java
// 类路径
private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
public static void main(String[] argv) {
.......
// 1 预加载资源
preload(bootTimingsTraceLog);
.......
// 2 准备SocketServer
zygoteServer = new ZygoteServer(isPrimaryZygote);
.......
if (startSystemServer) {
// 3 启动SystemServer进程
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
// 子进程,也就SystemServer进程,进入SystemServer.main()
r.run();
return;
}
}
.......
// Zygote进程等待连接 4 等待连接,fork子进程,初始化子进程,进入子进程入口。
caller = zygoteServer.runSelectLoop(abiList);
}
static void preload(TimingsTraceLog bootTimingsTraceLog) {
......
bootTimingsTraceLog.traceBegin("PreloadClasses");
preloadClasses(); // 加载系统class
.......
bootTimingsTraceLog.traceBegin("PreloadResources");
preloadResources(); // 加载资源
bootTimingsTraceLog.traceEnd();
.......
preloadSharedLibraries();
preloadTextResources();
}
// 预加载资源
private static void preloadClasses() {
InputStream is;
try {
is = new FileInputStream(PRELOADED_CLASSES);
} catch (FileNotFoundException e) {
Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
return;
}
......
Class.forName(line, true, null); // 加载类
.......
}
// 3 启动SystemServer进程
private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) {
......
// 启动SystemServer
pid = Zygote.forkSystemServer( parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, null, parsedArgs.mPermittedCapabilities, parsedArgs.mEffectiveCapabilities);
......
/* For child process */
if (pid == 0) {
// 子进程,也就是SystemServer进程
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
// 进程入口:调用SystemServer.main()
return handleSystemServerProcess(parsedArgs);
}
}
二 App进程启动
ActivityManagerService会通过调用startProcessLocked函数来向Zygote进程发送请求,主要流程如下:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
startProcessLocked() // final String entryPoint = "android.app.ActivityThread" 进程入口
startProcess()
frameworks/base/core/java/android/os/Process.java
start()
startViaZygote() // 拼接启动参数,包括entryPoint = "android.app.ActivityThread"
openZygoteSocketIfNeeded() // 连接Zygote socket
zygoteSendArgsAndGetResult() // 通过socket与Zygote进程通信,把启动参数传给Zygote进程
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
runSelectLoop() // zygote进程启动后,一直在runSelectLoop中等待client连接
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
processOneCommand() // fork子进程, 子进程返回Runnable对象。父进程返回null
Zygote.forkAndSpecialize() fork子进程
handleChildProc() // 子进程处理,
ZygoteInit.zygoteInit() //子进程初始化
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
main() // 子进程关闭socket,根据runSelectLoop返回的caller,调用android.app.ActivityThread.main()
ActivityManagerService调用Process.start()启动进程。
ActivityManagerService.java
private boolean startProcessLocked(String hostingType,
String hostingNameStr, String entryPoint, ProcessRecord app,
int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet,
String invokeWith, long startTime) {
........
final ProcessStartResult startResult = startProcess(app.hostingType,
entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
........
}
private ProcessStartResult startProcess(String hostingType,
String entryPoint, ProcessRecord app, int uid, int[] gids, i
nt runtimeFlags, int mountExternal, String seInfo,
String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
if (hostingType.equals("webview_service")) {
startResult = startWebView(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else {
startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
}
android.os.Process.java
public static final ProcessStartResult start(final String processClass,
final String niceName, int uid, int gid, int[] gids, int runtimeFlags,
int mountExternal, int targetSdkVersion, String seInfo, String abi,
String instructionSet, String appDataDir, String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi,
instructionSet, appDataDir, invokeWith, zygoteArgs);
}
ZygoteProcess:负责建立连接,拼接数据,传输数据
ZygoteProcess.java
private Process.ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, boolean startChildZygote, String[] extraArgs) throws ZygoteStartFailedEx {
......
// 拼接启动参数
synchronized(mLock) {
// openZygoteSocketIfNeeded() 建立连接,
// zygoteSendArgsAndGetResult() 使用连接,传输参数。
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
ZygoteInit:等待连接,创建ZygoteConnection对象(处理连接)。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
// Server端fd保存在第0个
fds.add(mServerSocket.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 {
// POLL监听,server端有连接或者client端有输入都会唤醒。
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) {
// 1 第0个是Server的fd,有连接请求
ZygoteConnection newPeer = acceptCommandPeer(abiList);
// 把连接加入数组,下一次for循环使用
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
// 取出{1处}连接
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
.......
// 子线程返回Runnable command
return command;
} else {
.......
}
} catch (Exception e) {
.......
}
}
}
}
}
// app进程初始化
public static final Runnable zygoteInit(int targetSdkVersion, 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();
// 设置setDefaultUncaughtExceptionHandler、setUncaughtExceptionPreHandler
RuntimeInit.commonInit();
// frameworks/base/core/jni/AndroidRuntime.cpp 创建Binder线程池
ZygoteInit.nativeZygoteInit();
// 设置堆,设置targetSdkVersion
// 找到main方法(android.app.ActivityThread.main()),封装成MethodAndArgsCaller,在ZygoteInit.main()中执行
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
ZygoteConnection:处理一次连接,fork子进程,通过ZygoteInit.zygoteInit()初始化子进程
ZygoteConnection.java
private final LocalSocket mSocket;
private final DataOutputStream mSocketOutStream;
private final BufferedReader mSocketReader;
ZygoteConnection(LocalSocket socket, String abiList) throws IOException {
mSocket = socket;
this.abiList = abiList;
mSocketOutStream = new DataOutputStream(socket.getOutputStream());
mSocketReader = new BufferedReader( new InputStreamReader(socket.getInputStream()), 256);
mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS);
try {
peer = mSocket.getPeerCredentials();
} catch (IOException ex) {
Log.e(TAG, "Cannot read peer credentials", ex);
throw ex;
}
isEof = false;
}
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
// 从连接中读取数据
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
.......
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, parsedArgs.runtimeFlags, rlimits,
parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore,
parsedArgs.startChildZygote, parsedArgs.instructionSet,
parsedArgs.appDataDir);
try {
if (pid == 0) {
// 子线程 zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
// 通过参数,初始化进程。返回Runnable,直接调用android.app.ActivityThread.main()
return handleChildProc(parsedArgs, descriptors, childPipeFd, parsedArgs.startChildZygote);
} 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;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) {
// 数据已传输完成,关闭连接
closeSocket();
.......
if (parsedArgs.invokeWith != null) {
.....
} else {
if (!isZygote) {
// app 进程。初始化进程
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */);
}
}
}
MethodAndArgsCaller:app进程入口封装。
RuntimeInit.java
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
// 进程入口
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}