Android开发—了解App启动过程

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

全部评论

相关推荐

来个大佬救一下,为上投了都是石沉大海了,没实习经历的话怕秋招直接进不了面。什么实习这么难找,基本
心态爆炸了:现在正式的岗位都少,实习基本不咋招的,除了大厂,中小企业其实没那么多岗位需求,就算是有,大多都是招一两个廉价劳动力,同时,他们也会希望你一来就能干活的,没时间培训你,就让你了解公司的项目,你了解完就可以开始干活。再者是,很多低质量的实习其实用处没有那么大的。我去年也是找实习找到破防,最后去了一家深圳的小公司实习,工作对我来说很简单,甚至不如我在学校做的项目,秋招的时候,这段实习经历也并没有帮上什么忙,投递简历,依旧非常低的回复率。低回复率是常态,尤其是找实习,找不到,那就把重心放在优化自己的简历和项目,多看八股文,锻炼自己的面试能力,多看别人的面经,自己模拟面试,等秋招的时候,只要有那么寥寥几次,好好抓住那几次机会。
点赞 评论 收藏
分享
06-10 21:15
门头沟学院 Java
宁阿:好多这种没🧠的公司,他们估计都不知道毕业的人不能给安排实习岗
实习吐槽大会
点赞 评论 收藏
分享
不亏是提前批,神仙打架,鼠鼠不配了
站队站对牛:现在92都报工艺岗了
投递韶音科技等公司7个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务