程序的启动是从进程启动开始的,换句话说只有程序进程启动后,程序才会加载和执行,在AMS启动程序时首先会判断当前进程是否启动,对未启动的进程会发送请求,Zygote在收到请求后创建新的进程;
由Android进阶知识树——Android系统的启动过程知道,系统的启动会执行到ZygoteInit.main()方法;
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();//1
zygoteServer.registerServerSocketFromEnv(socketName);
caller = zygoteServer.runSelectLoop(abiList); //2
}
在main中创建并注册了服务端的Socket,然后执行runSelectLoop()循环等待AMS的请求创建进程;
void registerServerSocketFromEnv(String socketName) {
if (mServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;//1
try {
String env = System.getenv(fullSocketName);//2
fileDesc = Integer.parseInt(env);
}
try {
FileDescriptor fd = new FileDescriptor();//3
fd.setInt$(fileDesc);
mServerSocket = new LocalServerSocket(fd);//4
mCloseSocketFd = true;
} catch (IOException ex) {
}
}
在registerServerSocketFromEnv中,首先使用ANDROID_SOCKET_PREFIX拼接Socket名称,最终的名称为ANDROID_SOCKET_zygote,然后将fullSocketName转换为环境变量的值,注释3处创建文件描述符,然后根据文件描述符创建LocalServerSocket对象
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
177 fds.add(mServerSocket.getFileDescriptor());//1
178 peers.add(null);
179
180 while (true) { //2
181 StructPollfd[] pollFds = new StructPollfd[fds.size()];
182 for (int i = 0; i < pollFds.length; ++i) {
183 pollFds[i] = new StructPollfd();
184 pollFds[i].fd = fds.get(i);
185 pollFds[i].events = (short) POLLIN;
186 }
187 try {
188 Os.poll(pollFds, -1);
189 } catch (ErrnoException ex) {
190 throw new RuntimeException("poll failed", ex);
191 }
192 for (int i = pollFds.length - 1; i >= 0; --i) {
193 if ((pollFds[i].revents & POLLIN) == 0) {
194 continue;
195 }
197 if (i == 0) { // 3
198 ZygoteConnection newPeer = acceptCommandPeer(abiList);
199 peers.add(newPeer);
200 fds.add(newPeer.getFileDesciptor());
201 } else {
202 try {
203 ZygoteConnection connection = peers.get(i);
204 final Runnable command = connection.processOneCommand(this); // 4
205
206 if (mIsForkChild) {
213 return command;
214 } else {
223 if (connection.isClosedByPeer()) {
224 connection.closeSocket();
225 peers.remove(i);
226 fds.remove(i);
227 }
228 }
229 } catch (Exception e) {
230 if (!mIsForkChild) {
241 ZygoteConnection conn = peers.remove(i);
242 conn.closeSocket();
244 fds.remove(i);
245 } else {
250 throw e;
251 }
252 } finally {
256 mIsForkChild = false;
257 }
258 }
259 }
260 }
261 }
在runSelectLoop方法中,首先获取注册Socket的文件描述符fd,并将其保存在fds集合中,然后开启循环监听AMS的请求,在注释3处判断i ==0,若i=0表示Socket已连接,否则表示接收到AMS的请求信号,调用connection.processOneCommand(this)创建新的进程,创建完成后清除对应的peers集合和fds集合;
AMS会检查目标程序进程,如果进程未启动则调用startProcessLocked()方法启动进程
int uid = app.uid; //1
......
if (ArrayUtils.isEmpty(permGids)) { //2
gids = new int[3];
} else {
gids = new int[permGids.length + 3];
System.arraycopy(permGids, 0, gids, 3, permGids.length);
}
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
.....
final String entryPoint = "android.app.ActivityThread"; //3
return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,startTime); //4
startProcessLocked执行一下逻辑:
在startProcessLocked()中又调用startProcess(),startProcess()中调用Process.start()方法,start中调用ZygoteProcess.startViaZygote()启动进程,
private Process.ProcessStartResult startViaZygote(final String processClass,
......String[] extraArgs)throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
在startViaZygote中首先创建ArrayList集合,然后添加创建进程的启动参数,最后调用zygoteSendArgsAndGetResult()执行启动进程,在zygoteSendArgsAndGetResult的第一个参数中首先调用了openZygoteSocketIfNeeded()方法,它的作用其实就是连接Zygote 中服务端的Socket
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(mSocket); //1
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
if (primaryZygoteState.matches(abi)) { //2
return primaryZygoteState;
}
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);//3
}
maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
}
if (secondaryZygoteState.matches(abi)) { //4
return secondaryZygoteState;
}
}
在openZygoteSocketIfNeeded()中ZygoteState.connect()连接Zygote进程中的Socket,连接成功后返回连接的主模式,用此主模式和传入的abi比较是否匹配,如果匹配则直接返回ZygoteState,否则连接zygote辅模式;
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
281 ZygoteState zygoteState, ArrayList<String> args)
282 throws ZygoteStartFailedEx {
283 try {
286 int sz = args.size();
287 for (int i = 0; i < sz; i++) {
288 if (args.get(i).indexOf('\n') >= 0) {
289 throw new ZygoteStartFailedEx("embedded newlines not allowed");
290 }
291 }
303 final BufferedWriter writer = zygoteState.writer;
304 final DataInputStream inputStream = zygoteState.inputStream;
306 writer.write(Integer.toString(args.size()));
307 writer.newLine();
309 for (int i = 0; i < sz; i++) {
310 String arg = args.get(i);
311 writer.write(arg);
312 writer.newLine();
313 }
315 writer.flush();
323 result.pid = inputStream.readInt();
324 result.usingWrapper = inputStream.readBoolean();
326 if (result.pid < 0) {
327 throw new ZygoteStartFailedEx("fork() failed");
328 }
329 return result;
330 } catch (IOException ex) {
331 zygoteState.close();
332 throw new ZygoteStartFailedEx(ex);
333 }
334 }
在zygoteSendArgsAndGetResult中获取连接Socket返回的ZygoteState,利用ZygoteState内部的BufferedWriter将请求参数写入Zygote进程中;
由第一部分知道,在AMS发送请求后zygote进程会接收请求,并调用ZygoteConnection.processOneCommand()方法处理请求,在ZygoteInit.main()方法中有以下代码
final Runnable caller;
caller = zygoteServer.runSelectLoop(abiList);
if (caller != null) {
caller.run();
}
在runSelectLoop()中接收到AMS请求信息后,然后执行处理并返回Runnable对象并执行run()方法,
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
args = readArgumentList(); //1
descriptors = mSocket.getAncillaryFileDescriptors();
}
parsedArgs = new Arguments(args); //2
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);
if (pid == 0) {
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote); //3
} else {
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
}
在processOneCommand()中首先调用readArgumentList读取参数数组,然后将数组封装在Arguments对象中,调用Zygote.forkAndSpecialize()方法fork子进程,子进程创建成功后调用handleChildProc()初始化进程
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,FileDescriptor pipeFd, boolean isZygote) {
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
}
在handleChildProc调用ZygoteInit.zygoteInit(),关于ZygoteInit.zygoteInit()方法的内容参考Android进阶知识树——Android系统的启动过程,其最终会使用反射调用ActivityThread.main()方法,程序进入进程初始化,关于ActivityThread中的操作这里不做分析,相信Android开发者应该了解;
本篇文章和上一篇Android进阶知识树——Android系统的启动过程中都提到Binder线程池的创建,但都没有详细介绍,这里补充一下,程序在启动进程后会调用ZygoteInit.zygoteInit()方法,zygoteInit中调用本地方法nativeZygoteInit(),在ZygoteInit中声明了nativeZygoteInit方法;
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();//
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
private static final native void nativeZygoteInit();
很明显nativeZygoteInit()是JNI方法(关于JNI见另一篇文章Android进阶知识树——JNI和So库开发),他在AndroidRuntime中完成方法动态注册,nativeZygoteInit中对应c文件中com_android_internal_os_ZygoteInit_nativeZygoteInit()方法
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
};
return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
methods, NELEM(methods));
}
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
在com_android_internal_os_ZygoteInit_nativeZygoteInit()方法中调用gCurRuntime.onZygoteInit(),这里的gCurRuntime是AppRuntime对象,它继承AndroidRuntime,在AndroidRuntime的构造函数中被初始化,AppRuntime类在app_main中实现
class AppRuntime : public AndroidRuntime
{
virtual void onZygoteInit() {
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool();
}
}
在onZygoteInit()中调用ProcessState类的startThreadPool(),startThreadPool()中调用
void ProcessState::spawnPooledThread(bool isMain){
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
在spawnPooledThread()中使用makeBinderThreadName()生成线程名称,然后创建PoolThread线程并执行线程
class PoolThread : public Thread{
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
PoolThread继承Thread类,启动PoolThread对象就创建了一个新的线程,在PoolThread的threadLoop()方法中调用IPCThreadState的joinThreadPool()方法将创建的线程加入Binder线程吃中,那么新创建的应用进程就支持Binder进程通行了;
总结一下整个进程启动的过程: