在Android的应用框架中,ActivityManagerService是非常重要的一个组件,尽管名字叫做ActivityManagerService,但通过之前的博客介绍,我们知道,四大组件的创建都是有AMS来完成的,其实不仅是应用程序中的组件,连Android应用程序本身也是AMS负责启动的。AMS本身运行在一个独立的进程中,当系统决定要在一个新的进程中启动一个Activity或者Service时就会先启动这个进程。而AMS启动进程的过程是从startProcessLocked启动的。
 
  1.ActivityManagerService.startProcessLocked
 
  public final class ActivityManagerService extends ActivityManagerNative  
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
    ......  
    
private final void startProcessLocked(ProcessRecord app,  
                String hostingType, String hostingNameStr) {  
        ......  
        
try {  
            
int uid = app.info.uid;  
            
int[] gids = 
null;  
            
try {  
                gids = mContext.getPackageManager().getPackageGids(  
                    app.info.packageName);  
            } 
catch (PackageManager.NameNotFoundException e) {  
                ......  
            }  
            ......  
            
int debugFlags = 
0;  
            ......  
            
int pid = Process.start(
"android.app.ActivityThread",  
                mSimpleProcessManagement ? app.processName : 
null, uid, uid,  
                gids, debugFlags, 
null);  
            ......  
        } 
catch (RuntimeException e) {  
            ......  
        }  
    }  
    ......  
}   
  
可以看到,函数会调用Process.start函数来创建一个进程,其中第一个参数”android.app.ActivityThread”是需要加载的类,而在完成这个类的加载之后就会运行ActivityThread.main函数。
 
  2.Process.start
 
  public class Process {
    ......
    
public static final int start(
final String processClass,
        
final String niceName,
        
int uid, 
int gid, 
int[] gids,
        
int debugFlags,
        String[] zygoteArgs)
    {
        
if (supportsProcesses()) {
            
try {
                
return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, zygoteArgs);
            } 
catch (ZygoteStartFailedEx ex) {
                ......
            }
        } 
else {
            ......
            
return 0;
        }
    }
    ......
} 
  
这个函数最后会调用startViaZygote来创建进程,而Zygote正是Android孵化进程的服务,所有的进程都是通过Zygotefork出来的,所以这里创建进程的任务又落到了Zygote头上了。
 
  3.Process.startViaZygote 
 
  public class Process {
    ......
    
private static int startViaZygote(
final String processClass,
            
final String niceName,
            
final int uid, 
final int gid,
            
final int[] gids,
            
int debugFlags,
            String[] extraArgs)
            
throws ZygoteStartFailedEx {
        
int pid;
        
synchronized(Process.class) {
            ArrayList<String> argsForZygote = 
new ArrayList<String>();
            
            
            argsForZygote.add(
"--runtime-init");
            argsForZygote.add(
"--setuid=" + uid);
            argsForZygote.add(
"--setgid=" + gid);
            
if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 
0) {
                argsForZygote.add(
"--enable-safemode");
            }
            
if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 
0) {
                argsForZygote.add(
"--enable-debugger");
            }
            
if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 
0) {
                argsForZygote.add(
"--enable-checkjni");
            }
            
if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 
0) {
                argsForZygote.add(
"--enable-assert");
            }
            
            
            
            
if (gids != 
null && gids.length > 
0) {
                StringBuilder sb = 
new StringBuilder();
                sb.append(
"--setgroups=");
                
int sz = gids.length;
                
for (
int i = 
0; i < sz; i++) {
                    
if (i != 
0) {
                        sb.append(
',');
                    }
                    sb.append(gids[i]);
                }
                argsForZygote.add(sb.toString());
            }
            
if (niceName != 
null) {
                argsForZygote.add(
"--nice-name=" + niceName);
            }
            argsForZygote.add(processClass);
            
if (extraArgs != 
null) {
                
for (String arg : extraArgs) {
                    argsForZygote.add(arg);
                }
            }
            pid = zygoteSendArgsAndGetPid(argsForZygote);
        }
    }
    ......
} 
  
函数里面最为重要的工作就是组装argsForZygote参数,这些参数将告诉Zygote具体的启动选项,例如”–runtime-init”就表示要为新启动的运行程序初始化运行库。然后调用zygoteSendAndGetPid函数进一步操作。
 
  4.Process.zygoteSendAndGetPid 
 
  public class Process {
    ......
    
private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
            
throws ZygoteStartFailedEx {
        
int pid;
        openZygoteSocketIfNeeded();
        
try {
            
/**
            * See com.android.internal.os.ZygoteInit.readArgumentList()
            * Presently the wire format to the zygote process is:
            * a) a count of arguments (argc, in essence)
            * b) a number of newline-separated argument strings equal to count
            *
            * After the zygote process reads these it will write the pid of
            * the child or -1 on failure.
            */
            sZygoteWriter.write(Integer.toString(args.size()));
            sZygoteWriter.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");
                }
                sZygoteWriter.write(arg);
                sZygoteWriter.newLine();
            }
            sZygoteWriter.flush();
            
            pid = sZygoteInputStream.readInt();
            
if (pid < 
0) {
                
throw new ZygoteStartFailedEx(
"fork() failed");
            }
        } 
catch (IOException ex) {
            ......
        }
        
return pid;
    }
    ......
} 
  
这里的sZygoteWriter是一个Socket写入流,是由openZygoteSocketIfNeeded函数打开的。而这个Socket由frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的ZygoteInit类在runSelectLoopMode函数侦听的。这个类会返回一个ZygoteConnection实例,并执行ZygoteConnection的runOnce函数。
 
  5.ZygoteConnection.runOnce 
 
  class ZygoteConnection {
    ......
    
boolean runOnce() 
throws ZygoteInit.MethodAndArgsCaller {
        String args[];
        Arguments parsedArgs = 
null;
        FileDescriptor[] descriptors;
        
try {
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } 
catch (IOException ex) {
            ......
            
return true;
        }
        ......
        
/** the stderr of the most recent request, if avail */
        PrintStream newStderr = 
null;
        
if (descriptors != 
null && descriptors.length >= 
3) {
            newStderr = 
new PrintStream(
                
new FileOutputStream(descriptors[
2]));
        }
        
int pid;
        
try {
            parsedArgs = 
new Arguments(args);
            applyUidSecurityPolicy(parsedArgs, peer);
            applyDebuggerSecurityPolicy(parsedArgs);
            applyRlimitSecurityPolicy(parsedArgs, peer);
            applyCapabilitiesSecurityPolicy(parsedArgs, peer);
            
int[][] rlimits = 
null;
            
if (parsedArgs.rlimits != 
null) {
                rlimits = parsedArgs.rlimits.toArray(intArray2d);
            }
            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids, parsedArgs.debugFlags, rlimits);
        } 
catch (IllegalArgumentException ex) {
            ......
        } 
catch (ZygoteSecurityException ex) {
            ......
        }
        
if (pid == 
0) {
            
            handleChildProc(parsedArgs, descriptors, newStderr);
            
            
return true;
        } 
else { 
            
            
return handleParentProc(pid, descriptors, parsedArgs);
        }
    }
    ......
} 
  
真正创建进程的代码在Zygote.forkAndSpecialize,通过Zygote来fork出一个新的进程作为应用进程。fork函数会有两个返回,其中一个在父进程,一个在子进程,其中自进程的进程号会为0,所以按照上面的代码,这里会执行handleChildProc。
 
  6.ZygoteConnection.handleChildProc 
 
  class ZygoteConnection {
    ......
    
private void handleChildProc(Arguments parsedArgs,
            FileDescriptor[] descriptors, PrintStream newStderr)
            
throws ZygoteInit.MethodAndArgsCaller {
        ......
        
if (parsedArgs.runtimeInit) {
            RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
        } 
else {
            ......
        }
    }
    ......
} 
  
因为在创建的时候传入了“–runtime-init”,所以这里会运行RuntimeInit.zygoteInit。
 
  public class RuntimeInit {
    ......
    
public static final void zygoteInit(String[] argv)
            
throws ZygoteInit.MethodAndArgsCaller {
        
        
        
        System.setOut(
new AndroidPrintStream(Log.INFO, 
"System.out"));
        System.setErr(
new AndroidPrintStream(Log.WARN, 
"System.err"));
        commonInit();
        zygoteInitNative();
        
int curArg = 
0;
        
for (  ; curArg < argv.length; curArg++) {
            String arg = argv[curArg];
            
if (arg.equals(
"--")) {
                curArg++;
                
break;
            } 
else if (!arg.startsWith(
"--")) {
                
break;
            } 
else if (arg.startsWith(
"--nice-name=")) {
                String niceName = arg.substring(arg.indexOf(
'=') + 
1);
                Process.setArgV0(niceName);
            }
        }
        
if (curArg == argv.length) {
            Slog.e(TAG, 
"Missing classname argument to RuntimeInit!");
            
            
return;
        }
        
        String startClass = argv[curArg++];
        String[] startArgs = 
new String[argv.length - curArg];
        System.arraycopy(argv, curArg, startArgs, 
0, startArgs.length);
        invokeStaticMain(startClass, startArgs);
    }
    ......
} 
  
这里有两个关键的函数调用,一个是zygoteInitNative函数调用,一个是invokeStaticMain函数调用,前者就是执行Binder驱动程序初始化的相关工作了,正是由于执行了这个工作,才使得进程中的Binder对象能够顺利地进行Binder进程间通信,而后一个函数调用,就是执行进程的入口函数,这里就是执行startClass类的main函数了,而这个startClass即是我们在Step 1中传进来的”android.app.ActivityThread”值,表示要执行android.app.ActivityThread类的main函数。
 
  7. Zygote.invokeStaticMain 
 
  public class ZygoteInit {
    ......
    
static void invokeStaticMain(ClassLoader loader,
            String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;
        
try {
            cl = loader.loadClass(className);
        } 
catch (ClassNotFoundException ex) {
            ......
        }
        Method m;
        
try {
            m = cl.getMethod(
"main", 
new Class[] { String[].class });
        } 
catch (NoSuchMethodException ex) {
            ......
        } 
catch (SecurityException ex) {
            ......
        }
        
int modifiers = m.getModifiers();
        ......
        
        
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }
    ......
} 
  
从代码中可以看到,通过ClassLoader加载对应的android.app.ActivityThread类,然后再获取到对应的main函数句柄,最后调用该类的main函数。不过这里的调用方式比较有意思,不知直接调用,而是通过抛出一个异常。这样做的方式是为了清空堆栈,让系统认为新进程是从ActivityThread的main函数开始的。
 
  8.ActivityThread.main
 
  public final class ActivityThread {
    ......
    
public static final void main(String[] args) {
        SamplingProfilerIntegration.start();
        Process.setArgV0(
"<pre-initialized>");
        Looper.prepareMainLooper();
        
if (sMainThreadHandler == 
null) {
            sMainThreadHandler = 
new Handler();
        }
        ActivityThread thread = 
new ActivityThread();
        thread.attach(
false);
        
if (
false) {
            Looper.myLooper().setMessageLogging(
new
                LogPrinter(Log.DEBUG, 
"ActivityThread"));
        }
        Looper.loop();
        
if (Process.supportsProcesses()) {
            
throw new RuntimeException(
"Main thread loop unexpectedly exited");
        }
        thread.detach();
        String name = (thread.mInitialApplication != 
null)
            ? thread.mInitialApplication.getPackageName()
            : 
"<unknown>";
        Slog.i(TAG, 
"Main thread of " + name + 
" is now exiting");
    }
    ......
} 
  
从这里我们可以看出,这个函数首先会在进程中创建一个ActivityThread对象,然后进入消息循环中,这样,我们以后就可以在这个进程中启动Activity或者Service了。