**一、作用 **
同时还可以参考juejin.cn/post/684490…
ActivityThread是整个Android app启动的入口。里面有java的入口类
public static void main(String[] args) {
// 一些日志追踪的初始化、Environment存储当前app的data/data目录,Process设置标志位等
Looper.prepareMainLooper();
ActivityThread activityThread = new ActivityThread();
activityThread.attach(false);
Looper.loop();
}
从上面的java入口类里面,我们是不是很简单的看到,app启动,主要有两部分, 1:Handler(所有消息通知,比如生命周期,会用到它) 2:attach方法(app的第一个入口)
备注:我们看到在调用attach的时候,传了一个false,那么肯定还有一个地方会调用true,查询源码我们定位到,ActivityThread里面还有一个方法
public static ActivityThread systemMain(),该方法里面的内容如下:
public static ActivityThread systemMain() {
// The system process on low-memory devices do not get to use hardware
// accelerated drawing, since this can add too much overhead to the
// process.
if (!ActivityManager.isHighEndGfx()) {
ThreadRenderer.disable(true);
} else {
ThreadRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
thread.attach(true);
return thread;
}
从systemMain里面,我们可以清楚的看到,他是跟硬加速有关的一个入口类.而systemMain方法的调用地方则是在SystemServer的private void createSystemContext() {}里面,createSystemContext内部实现如下:
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
那么,systemServer是干什么的呢,那就得知道Android的启动流程
参考自:https://blog.csdn.net/wangjia55/article/details/45438797
Google说,伊甸园(Linux)要被隔离,于是创建了亚当(system_server)与夏娃(zygote)。夏娃(zygote)用自己的肋骨(fork)创建了亚当(system_server)。
从这里我们看出,systemServer是我们启动app之后,java层的第一个类,在它的main函数里面,会做Android相关的所有操作,可以参考:https://juejin.cn/post/6844903911942275079。
主要分为3类:
1、系统级别的功能:startBootstrapServices();比如,设备电源管理服务PowerManagerService、LED服务LightsService、包管理器PackageManagerService、传感器SensorService等
2、基本服务:startCoreServices();比如:应用统计服务UsageStatsService,生成和管理系统运行时的一些日志文件DropBoxManagerService等
3、startOtherServices();比如,闹钟AlarmManagerService,看门狗Watchdog等。
zygote调用systemServer是通过ZygoteInit类,代码如下:
public class ZygoteInit {
xxx
public static void main(String[] argv) {
XXX
try {
//1、注册一个localSocket
zygoteServer.registerServerSocket(socketName);
//遍历argv数组,如果里面有start-system-server,那么调用SystemServer类,代码如下:
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
}else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
}else if (argv[i].startsWith(ABI_LIST_ARG)) {
//abi 表示手机的cpu,不同手机,对应不同的cpu
abiList = argv[i].substring(ABI_LIST_ARG.length());
}
}
//2、如果需要预加载,会先预加载一些资源,包括 openGL、一些类(反射)、webview 内核等。作用,第一次会预加载一些系统资源,之后,再fork新的进程的时候,可以直接copy一份,不需要重新再加载一遍
if (!enableLazyPreload) {
preload(bootTimingsTraceLog);
} else {
//设置当前线程的优先级
Zygote.resetNicePriority();
}
//3、反射的方式,启动SystemServer,调用main函数
if (startSystemServer) {
//启动ServerSocket,同时close localSocket(zygoteServer.closeServerSocket())
startSystemServer(abiList, socketName, zygoteServer);
}
XXX
//4、阻塞式的等待下一个socket事件
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
//上面3中,最后调用main方法,实际上式从这个里面去调用main函数的
caller.run();
}
}
xxx
}
上面代码里面有一个abilist,关于abi的知识,见developer.android.com/ndk/guides/…
上面我们一直说的是系统启动SystemServer进程,然后执行SystemServer的main方法。那么什么时候执行ActivityThread的main方法呢。我们看到,上面有一个阻塞式的等待下一个socket的事件,我们看一下里面的源码:
void runSelectLoop(String abiList) {
while(true) {
XXX
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
//没有接收到socket回调的事件,继续循环
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
//执行fork新process的操作
boolean done = peers.get(i).runOnce(this);
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
我们再看runOnce方法里面的具体实现,这个方法,位于SocketConnection里面
boolean runOnce(ZygoteServer zygoteServer) {
XXX
String args[];
Arguments parsedArgs = null;
args = readArgumentList();
parsedArgs = new Arguments(args);
//做一些系统级别的一些内容,比如,设置abi,预加载
//因为之前已经fork了一个SystemServer,那个时候,已经设置了一些系统内容,在这里只要再检测一下
if (parsedArgs.abiListQuery) {
return handleAbiListQuery();
}
if (parsedArgs.preloadDefault) {
return handlePreload();
}
XXXX
//fork一个进程
pid = Zygote.forkAndSpecialize();
if (pid == 0) {
// in child,执行子进程
zygoteServer.closeServerSocket();
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
return true;
} else {
// in parent...pid of < 0 means failure,是parent本身,做一些close操作
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
}
我们再看看handleChildProc里面都有什么:
private void handleChildProc(){
XXX
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
} else {
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
我们看到,会判断参数里面是否有invokeWith,如果有,则走WrapperInit,否则走ZygoteInit。首先,解释一下,WrapperInit对应的是普通的java进程,ZygoteInit对应的是应用进程,这个里面会通过返回调用ActivityThread的main函数。可以参考liwenkun.me/2017/08/29/…