美文网首页
Activity启动分析

Activity启动分析

作者: 蒸汽飞船 | 来源:发表于2018-07-10 23:20 被阅读25次

    启动activity步骤详解
    详解2

    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<ActivityRecord> mHistory;//活动列表
    List<ActivityRecord> mLRUActivitys; //最近任务列表
    List<ActivityRecord> mPnedingActivityLaunches;//pending列表
    List<ActivityRecord> mStopingActivitys;//理念先启动,在停止,启动2时1先放这里,等2启动完毕,再来处理
    List<ActivityRecord> mFinishingActivitys;//结束的,不回直接销毁,等内存不足才销毁。

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

    ProcessRecord进程信息:

    Applicationinfo:
    进程名
    HashSet<String> 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<AMS>),Instrumentation负责管理并完成老板交待的任务。

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

    1. 创建: callActivityOnCreate
    2. 暂停: callActivityOnPause
    3. 恢复: callActivityOnResume
    Instrumentation主要方法:
    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:


    流程参考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对象;  
                     <LoadedApk.makeApplication>  
                  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启动分析

          本文链接:https://www.haomeiwen.com/subject/zrmweftx.html