Android基础四大组件之Activity的启动过程源码解析

本文详细解析了Android中Activity的启动过程,从startActivity开始,经过Instrumentation、ActivityThread和ApplicationThread,深入源码,阐述了Activity如何被创建及执行onCreate方法,帮助读者理解Activity启动背后的机制。
摘要由CSDN通过智能技术生成

前言

Activity是Android中一个很重要的概念,堪称四大组件之首,关于Activity有很多内容,比如生命周期和启动Flags,这二者想要说清楚,恐怕又要写两篇长文,更何况分析它们的源码呢。不过本文的侧重点不是它们,我要介绍的是一个Activity典型的启动过程,本文会从源码的角度对其进行分析。我们知道,当startActivity被调用的时候,可以启动一个Activity,但是你知道这个Activity是如何被启动的吗?每个Activity也是一个对象,你知道这个对象是啥时候被创建的吗(也就是说它的构造方法是什么时候被调用的)?为什么onCreate是Activity的执行入口?所有的这一切都被系统封装好了,对我们来说是透明的,我们使用的时候仅仅是传递一个intent然后startActivity就可以达到目的了,不过,阅读了本文以后,你将会了解它的背后到底做了哪些事情。在分析之前,我先介绍几个类:

  • Activity:这个大家都熟悉,startActivity方法的真正实现在Activity中
  • Instrumentation:用来辅助Activity完成启动Activity的过程
  • ActivityThread(包含ApplicationThread + ApplicationThreadNative +IApplicationThread):真正启动Activity的实现都在这里

源码分析

首先看入口

code:Activity#startActivity

@Override 
public void startActivity(Intent intent) {
    
 startActivity(intent, null); 
} 
 
@Override 
public void startActivity(Intent intent, Bundle options) {
    
 if (options != null) {
    
  startActivityForResult(intent, -1, options); 
 } else {
    
  // Note we want to go through this call for compatibility with 
  // applications that may have overridden the method. 
  startActivityForResult(intent, -1); 
 } 
} 
 
public void startActivityForResult(Intent intent, int requestCode) {
    
 startActivityForResult(intent, requestCode, null); 
} 

说明:显然,从上往下,最终都是由startActivityForResult来实现的

接着看

code:Activity#startActivityForResult

public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
    
 //一般的Activity其mParent为null,mParent常用在ActivityGroup中,ActivityGroup已废弃 
 if (mParent == null) {
    
  //这里会启动新的Activity,核心功能都在mMainThread.getApplicationThread()中完成 
  Instrumentation.ActivityResult ar = 
   mInstrumentation.execStartActivity( 
    this, mMainThread.getApplicationThread(), mToken, this, 
    intent, requestCode, options); 
  if (ar != null) {
    
   //发送结果,即onActivityResult会被调用 
   mMainThread.sendActivityResult( 
    mToken, mEmbeddedID, requestCode, ar.getResultCode(), 
    ar.getResultData()); 
  } 
  if (requestCode  = 0) {
    
   // If this start is requesting a result, we can avoid making 
   // the activity visible until the result is received. Setting 
   // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 
   // activity hidden during this time, to avoid flickering. 
   // This can only be done when a result is requested because 
   // that guarantees we will get information back when the 
   // activity is finished, no matter what happens to it. 
   mStartedActivity = true; 
  } 
 
  final View decor = mWindow != null ? mWindow.peekDecorView() : null; 
  if (decor != null) {
    
   decor.cancelPendingInputEvents(); 
  } 
  // TODO Consider clearing/flushing other event sources and events for child windows. 
 } else {
    
  //在ActivityGroup内部的Activity调用startActivity的时候会走到这里,内部处理逻辑和上面是类似的 
  if (options != null) {
    
   mParent.startActivityFromChild(this, intent, requestCode, options); 
  } else {
    
   // Note we want to go through this method for compatibility with 
   // existing applications that may have overridden it. 
   mParent.startActivityFromChild(this, intent, requestCode); 
  } 
 } 
} 

说明:上述代码关键点都有注释了,可以发现,真正打开activity的实现在Instrumentation的execStartActivity方法中,去看看

code:Instrumentation#execStartActivity

public ActivityResult execStartActivity( 
  Context who, IBinder contextThread, IBinder token, Activity target, 
  Intent intent, int requestCode, Bundle options) {
    
 //核心功能在这个whoThread中完成,其内部scheduleLaunchActivity方法用于完成activity的打开 
 IApplicationThread whoThread = (IApplicationThread) contextThread; 
 if (mActivityMonitors != null) {
    
  synchronized (mSync) {
    
   //先查找一遍看是否存在这个activity 
   final int N = mActivityMonitors.size(); 
   for (int i=0; i<N; i++) {
    
    final ActivityMonitor am = mActivityMonitors.get(i); 
    if (am.match(who, null, intent)) {
    
     //如果找到了就跳出循环 
     am.mHits++; 
     //如果目标activity无法打开,直接return 
     if (am.isBlocking()) {
    
      return requestCode  = 0 ? am.getResult() 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值