Activity启动分析

启动activity步骤详解
详解2

Activity启动分析_第1张图片
image.png

ActivityThread-attach-ams.attachApplication将AppThread传给AMS
ActivityManagerNative extends Binder??
ActivityManagerNative->asInterface->ActivityManagerProxy
ActivityThread.attach:

bindapplication参数AppBindData
launchActivity参数ActivityClientRecord
解析activity信息
startActivityLocked:保存调用者信息
unckeckLocked:检查栈信息
resumeTopActivityLokced:检查Pause信息,(看resumeActivity为不为空)
startSpecificActivityLocked:检查是否有对应的进程,fork-main-attach-准备完毕
realStartActivityLocked:ipc调 ApplicationThread.scheduleLaunchActivity-> ActivityThread.handleLaunchActivity-> ActivityThread.performLaunchActivity,参数为ActivityClientRecord
performLaunchActivity: Instrumentation.newActivity: 加载新类,即创建Activity对象;
2) ActivityClientRecord.packageInfo.makeApplication:创建Application对象;一般已有
Activity.attach- Instrumentation.callActivityOnCreate- ActivityThread.handleResumeActivity

AMS变量:
List mHistory;//活动列表
List mLRUActivitys; //最近任务列表
List mPnedingActivityLaunches;//pending列表
List mStopingActivitys;//理念先启动,在停止,启动2时1先放这里,等2启动完毕,再来处理
List mFinishingActivitys;//结束的,不回直接销毁,等内存不足才销毁。

mPausingActivity;//只有正在暂停某Activity时才有值
mResumedActivity; //前台运行的Activity,
mFocusedActivity;
mLastPausedActivity;

ProcessRecord进程信息:

Applicationinfo:
进程名
HashSet pkglist;进程里的所有apk的包名
所有的activitys\provides\services

ActivityRecord

Activity对应的档案信息:
Activity的信息等、package、进程名,状态:idle\stop\finishing等

TaskRecord:

保存Activity的启动和退出信息:
int taskid; //task id
Intent intent; //创建该Task对应的intent
int numActivitys; //该task下的activity数目
TaskRecord中并没有该Task下所有的ActivityRecord列表,想要看的话需要从AMS的mHistory列表遍历查找,AMS的mHistory列表顺序是按task排的,最上面的是最前面显示的。

Instrumentation和ActivityThread的关系,类似于老板与经理的关系,老板负责对外交流(如与Activity Manager Service),Instrumentation负责管理并完成老板交待的任务。

当ActivityThread 创建(callActivityOnCreate)、暂停、恢复某个Activity时,通过调用此对象的方法来实现,如:

  1. 创建: callActivityOnCreate
  2. 暂停: callActivityOnPause
  3. 恢复: callActivityOnResume
Instrumentation主要方法:
Activity启动分析_第2张图片
Instrumentation
  1. 在Android系统里面,zygote是一个进程的名字。
  2. Android是基于Linux System的,当你的手机开机的时候,Linux的内核加载完成之后就会启动一个叫“init“的进程。在Linux System里面,所有的进程都是由init进程fork出来的,
  3. 我们的zygote进程也不例外。
  4. SystemServer也是一个进程,是由zygote进程fork出来的。
  5. App进程也是zygote进程fork出来的

流程1:

在zygote开启的时候,会调用ZygoteInit.main()进行初始化

  1. 方法里fork了SystemServer进程:
  2. 调用startSystemServer()方法

调用SystemServer.main方法:

  1. 创建SystemServiceManager并启动各种服务
  2. 创建系统上下文mSystemContext是一个ContextImpl对象

此时:我们的ActivityManagerService对象已经创建好了,并且完成了成员变量初始化。而且在这之前,调用createSystemContext()创建系统上下文的时候,也已经完成了mSystemContext和ActivityThread的创建。

App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。

关键剪口:IActivityManager
1.ActivityManagerService实现了该接口
2.本地ActivityManagerNative也实现了该接口,ActivityManagerNative拿到了ActivityManagerService的本地代理(IActivityManager对象),并包装成了ActivityManagerProxy对象。
3.所以ActivityManagerService在客户端的代理就是ActivityManagerProxy

本地调Ams:
ActivityManagerProxy:
Ams调本地:
ApplicationThreadProxy:

IApplicationThread当创建Application时,将把此Binder对象传递给AMS,然后AMS把它保存在mProcessNames.ProcessRecord.thread中。当需要通知Application工作时,则调用IApplicationThread中对应的接口函数。

ActivityManagerService端使用ActivityStack来管理系统中所有的Activities的状态,Activities使用stack的方式进行管理。它是真正负责做事的家伙,

应用的启动入口:

ActivityThread.main()方法:
    1.ooper.prepareMainLooper();
    2.ActivityThread thread = new ActivityThread();
    4.AsyncTask.init();
    5.Looper.loop();
    3.thread.attach(false);    
        1.IActivityManager mgr = ActivityManagerNative.getDefault();//AMS本地代理
        2.mgr.attachApplication(mAppThread);//ApplicationThread mAppThread = new ApplicationThread();
                                            //一个ActivityThread有一个,实现了IApplicationThread接口
                                            //这里是通过rpc调用ams的attachApplication方法
                                            //在此方法里将ApplicationThread的binder传给了AMS,这样AMS
                                            //就拿到了客户端的一个连接:ApplicationThreadProxy

            //ams服务端的attachApplication方法的
            1.attachApplicationLocked(mAppThread, callingPid);
                1.mAppThread.bindApplication//这里又会通过IPC调用到到本地的ApplicationThread的对应方法

                    //客户端的ApplicationThread的bindApplication方法
                    1.handleBindApplication//通过handler、msg调用的
                        1.mInstrumentation创建  
                        3.mInstrumentation.callApplicationOnCreate(app);    //appication oncreate
                        2.Application app = data.info.makeApplication(...)//data.info是一个LoadeApk对象

                            1.ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);//创建应用context
                            2.app = mInstrumentation.newApplication...//mInstrumentation创建application
                                 1.Application app = (Application)clazz.newInstance();
                                 2.app.attach(context); //所以是先调用的attach

Activity启动流程:

1.startActivityForResult-》
2.mInstrumentation.execStartActivity
ActivityManagerNative.getDefault().startActivity//RPC调用AMS的方法
//准备完成后 RPC调用客户端ApplicationThread.scheduleLaunchActivity
3.ApplicationThread.scheduleLaunchActivity
4.发消息调用ActivityThread.handleLaunchActivity
5.ActivityThread.performLaunchActivity

流程参考1:


Activity启动分析_第3张图片
流程参考1

ActivityStack.startActivityLocked:
1.处理传进来的参数caller,得到调用者的进程信息,并保存在callerApp变量中 ProcessRecord类型















主要对象功能介绍

我们下面的文章将围绕着这几个类进行介绍。可能你第一次看的时候,印象不深,不过没关系,当你跟随者我读完这篇文章的时候,我会在最后再次列出这些对象的功能,相信那时候你会对这些类更加的熟悉和深刻。

  1. ActivityManagerServices,简称AMS,服务端对象,负责系统中所有Activity的生命周期
  2. ActivityThread,App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作
  3. ApplicationThread,用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。
  4. ApplicationThreadProxy,是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。
  5. Instrumentation,每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
  6. ActivityStack,Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
  7. ActivityRecord,ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息。其实就是服务器端的Activity对象的映像。
  8. TaskRecord,AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。如果你清楚Activity的4种launchMode,那么对这个概念应该不陌生。




每一个App其实都是

  1. 一个单独的dalvik虚拟机
  2. 一个单独的进程
    所以当系统里面的第一个zygote进程运行之后,在这之后再开启App,就是通过fork第一个zygote进程实现的。所以说,除了第一个zygote进程,其他应用所在的进程都是zygote的子进程。这下你明白为什么这个进程叫“受精卵”了吧?



//初始化系统上下文对象mSystemContext,并设置默认的主题,mSystemContext实际上是一个ContextImpl对象。调用ActivityThread.systemMain()的时候,会调用ActivityThread.attach(true),而在attach()里面,则创建了Application对象,并调用了Application.onCreate()。
private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}






Launcher启动app参考1

/***************************************************************** 
 * Launcher通过Binder告诉ActivityManagerService, 
 * 它将要启动一个新的Activity; 
 ****************************************************************/  
Launcher.startActivitySafely->    
Launcher.startActivity->    
 //要求在新的Task中启动此Activity    
 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)    
 Activity.startActivity->    
 Activity.startActivityForResult->    
 Instrumentation.execStartActivity->    
  // ActivityManagerNative.getDefault()返回AMS Proxy接口    
  ActivityManagerNative.getDefault().startActivity->    
  ActivityManagerProxy.startActivity->    
    
   ActivityManagerService.startActivity-> (AMS)    
   ActivityManagerService.startActivityAsUser->     
    
    ActivityStack.startActivityMayWait->    
    ActivityStack.resolveActivity(获取ActivityInfo)    
      //aInfo.name为main Activity,如:com.my.test.MainActivity    
      //aInfo.applicationInfo.packageName为包名,如com.my.test    
    ActivityStack.startActivityLocked->    
      //ProcessRecord callerApp; 调用者即Launcher信息    
      //ActivityRecord sourceRecord; Launcher Activity相关信息    
      //ActivityRecord r=new ActivityRecord(...),将要创建的Activity相关信息      
    ActivityStack.startActivityUncheckedLocked->    
     //Activity启动方式:ActivityInfo.LAUNCH_MULTIPLE/LAUNCH_SINGLE_INSTANCE/    
     //             ActivityInfo.LAUNCH_SINGLE_TASK/LAUNCH_SINGLE_TOP)    
     // 创建一个新的task,即TaskRecord,并保存在ActivityRecord.task中    
     //r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true)    
     // 把新创建的Activity放在栈顶       
     ActivityStack.startActivityLocked->    
     ActivityStack.resumeTopActivityLocked->    
     ActivityStack.startPausingLocked (使Launcher进入Paused状态)->      
  
     /***************************************************************** 
      * AMS通过Binder通知Launcher进入Paused状态 
      ****************************************************************/  
      ApplicationThreadProxy.schedulePauseActivity->     
      //private class ApplicationThread extends ApplicationThreadNative    
      ApplicationThread.schedulePauseActivity->    
    
       ActivityThread.queueOrSendMessage->    
     
       // 调用Activity.onUserLeaveHint    
       // 调用Activity.onPause    
       // 通知activity manager我进入了pause状态    
       ActivityThread.handlePauseActivity->    
  
       /***************************************************************** 
        * Launcher通过Binder告诉AMS,它已经进入Paused状态 
        ****************************************************************/  
       ActivityManagerProxy.activityPaused->    
       ActivityManagerService.activityPaused->    
       ActivityStack.activityPaused->(把Activity状态修改为PAUSED)    
       ActivityStack.completePauseLocked->    
      
       // 参数为代表Launcher这个Activity的ActivityRecord    
       // 使用栈顶的Activity进入RESUME状态    
       ActivityStack.resumeTopActivityLokced->    
         //topRunningActivityLocked将刚创建的放于栈顶的activity取回来    
         // 即在ActivityStack.startActivityUncheckedLocked中创建的    
  
       /***************************************************************** 
        * AMS创建一个新的进程,用来启动一个ActivityThread实例, 
        * 即将要启动的Activity就是在这个ActivityThread实例中运行 
        ****************************************************************/  
       ActivityStack.startSpecificActivityLocked->    
    
        // 创建对应的ProcessRecord    
        ActivityManagerService.startProcessLocked->    
            
         // 启动一个新的进程    
         // 新的进程会导入android.app.ActivityThread类,并且执行它的main函数,    
         // 即实例化ActivityThread, 每个应用有且仅有一个ActivityThread实例    
         Process.start("android.app.ActivityThread",...)->    
  
         // 通过zygote机制创建一个新的进程    
         Process.startViaZygote->    
      
         // 这个函数在进程中创建一个ActivityThread实例,然后调用    
         // 它的attach函数,接着就进入消息循环    
         ActivityThread.main->    
  
         /***************************************************************** 
          * ActivityThread通过Binder将一个ApplicationThread类的Binder对象 
          * 传递给AMS,以便AMS通过此Binder对象来控制Activity整个生命周期 
          ****************************************************************/  
         ActivityThread.attach->    
         IActivityManager.attachApplication(mAppThread)->    
         ActivityManagerProxy.attachApplication->    
         ActivityManagerService.attachApplication->    
    
         // 把在ActivityManagerService.startProcessLocked中创建的ProcessRecord取出来    
         ActivityManagerService.attachApplicationLocked->    
  
         /***************************************************************** 
          * AMS通过Binder通知ActivityThread一切准备OK,它可以真正启动新的Activity了 
          ****************************************************************/              
         // 真正启动Activity    
         ActivityStack.realStartActivityLocked->    
         ApplicationThreadProxy.scheduleLaunchActivity->    
         ApplicationThread.scheduleLaunchActivity->    
         ActivityThread.handleLaunchActivity->    
           // 加载新的Activity类,并执行它的onCreate    
           ActivityThread.performLaunchActivity    
            /*1) Instrumentation.newActivity: 加载新类,即创建Activity对象;  
              2) ActivityClientRecord.packageInfo.makeApplication:创建Application对象;  
                   
              3) Activity.attach(Context context, ActivityThread aThread,  
                    Instrumentation instr, IBinder token, int ident,  
                    Application application, Intent intent, ActivityInfo info,  
                    CharSequence title, Activity parent, String id,  
                    NonConfigurationInstances lastNonConfigurationInstances,  
                    Configuration config):把Application attach到Activity, 即把Activtiy  
                                           相关信息设置到新创建的Activity中  
              4) Instrumentation.callActivityOnCreate:调用onCreate;*/    
      
           // 使用Activity进入RESUMED状态,并调用onResume    
           ActivityThread.handleResumeActivity    

你可能感兴趣的:(Activity启动分析)