app的启动过程

1. 关于Android系统的启动

系统的启动过程非常复杂,这里只是简单的了解。 先上谷歌提供的架构分层图⬇

** 引导程序BootLoader进行初始化Linux内核->启动init进程->init进程fork出zygote进程(处于c++ framework层)->zygote进程fork出system_server进程(处于java framework层) **

  • system_server进程负责启动和管理整个java framwork层包含ActivityManagerService、PackageManagerService、WindowManagerService等服务

    service的本质是Binder我们可以看ActivityManagerService的实现,是继承了Binder的子类Stub

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {}

  • Zygote进程fork出的APP层的第一个进程是Launch进程,就是用户看到的桌面
  • 所有的app进程都是由zygote进程fork的

2. APP的启动过程

  • 当点击桌面app时,launch进程中的startActvity方法通过binder通信调用system_server进程管理的AMS中的startActivity,而AMS又继续调用ATMS(# ActivityTaskManagerService)的StartActivity方法进行真正的启动.
  • system_server进程收到消息后向Zygote进程发送创建进程的请求(通过socket通信)
  • Zygote进程fork出app进程,并执行ActivityThread的main方法
源码基于android API 31
public static void main(String[] args) {
    //安装sysCall Native与Kernel之间有一层系统调用(SysCall)层
    AndroidOs.install();
    CloseGuard.setEnabled(false);
    Environment.initForCurrentUser();
    //获取用户空间的配置文件
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);
    //初始化每个进程(MediaServiceManager,TelphoneServiceManager) 
    initializeMainlineModules();
    //初始化主线程looper
    Looper.prepareMainLooper();

    long startSeq = 0;
    if (args != null) {
        for (int i = args.length - 1; i >= 0; --i) {
            if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                startSeq = Long.parseLong(
                        args[i].substring(PROC_START_SEQ_IDENT.length()));
            }
        }
    }
    //真正的主角
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

  • 从main方法中可以看到创建ActivityThread之后调用了thread.attach(false, startSeq)方法,并同时初始化ApplicationThread用于和AMS通信
  • App进程,通过Binder向sytem_server进程发起attachApplication请求,这里实际上就是APP进程通过Binder调用sytem_server进程中AMS的attachApplication方法,AMS的attachApplication方法的作用是将ApplicationThread对象与AMS绑定
  • system_server进程在收到attachApplication的请求,进行一些准备工作后,再通过binder IPC向App进程发送handleBindApplication请求(初始化Application并调用onCreate方法)和scheduleLaunchActivity请求(创建启动Activity)
  • App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送BIND_APPLICATION和LAUNCH_ACTIVITY消息,这里注意的是AMS和主线程并不直接通信,而是AMS和主线程的内部类ApplicationThread通过Binder通信,ApplicationThread再和主线程通过Handler消息交互。
  • 主线程在收到Message后,创建Application并调用onCreate方法,再通过反射机制创建目标Activity,并回调Activity.onCreate()等方法
  • 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染后显示APP主界面

最后,我整理了一些学习资料,里面包括Java基础、Android进阶、架构设计、NDK、音视频开发、跨平台、底层源码等技术,还有2022年一线大厂最新面试题集锦,都分享给大家,助大家学习路上披荆斩棘~ 能力得到提升,思维得到开阔~ 有需要的可以点击下方公号链接免费获取。

公众号链接:https://mp.weixin.qq.com/s/HQgjJ5vMFvLh_7u1KizHiA