Android ActivtyThread类

351 阅读4分钟

**一、作用 **

同时还可以参考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/…