其他分享
首页 > 其他分享> > Activity启动流程宏观概念分析

Activity启动流程宏观概念分析

作者:互联网

本文借鉴自两位大神的原创:https://blog.csdn.net/singwhatiwanna/article/details/18154335

                                               https://blog.csdn.net/qq_23547831/article/details/51224992

这两篇启动流程的总结,个人认为是很有代表性的两个极端总结,第一篇相对简短,只介绍了核心流程,大概五六分钟就能看完;第二篇十分详细,详细到连新进程的启动流程都涉及到了,看完大概需要半个小时甚至更长时间。

首先最好了解一下启动过程中比较重要的几个类,要知道它们的功能作用。

1.Instrumentation

      Instrumentation是android系统中启动Activity的一个实际操作类,Activity的onCreate、onStart、onResume等都是由它调用;

2.ActivityThread

     启动Activity的核心功能由其内部的scheduleLaunchActivity方法来完成。

3.ActivityManagerService(AMS)

     四大组件的大管家,统一调度各应用进程。

Activity的启动分两种,一种是startActivity(intent),另一种是Launcher启动,也就是点击桌面上的图标。

<activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <!--这个LAUNCHER过滤条件就决定了该Activity是由桌面点击图标启动的-->
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>

整体、大致流程

  1. startActivity方法最终会调用startActivityForResult方法,接着又调用的InstrumentationexecStartActivity方法通知AMS启动下一个Activity;
  2. AMS记录要启动的Activity信息,并且通知前一个Activity进入pause状态。
  3. 前一个Activity进入pause状态后,通知AMS已经paused了,可以启动下一个了。
  4. 如果被启动的Activity的进程不存在,也就是Launcher启动,所以AMS启动新的进程,并且在新进程中创建ActivityThread对象,执行其中的main函数方法。
  5. 被启动的Activity主线程启动完毕后通知AMS,并传入ApplicationThread以便通讯。
  6. 被启动的Activity启动后创建和关联Context,最后调用onCreate方法。

Launcher启动只能是隐式的启动,因为Launcher启动Activity会开启一个新的进程,这个进程与Launcher不在同一个进程,所以就无法引用到启动的Activity的字节码(.class),也就无法启动这个Activity。

首先我们要知道Acitivty的启动分为应用进程端的启动SystemServer服务进程端的启动

应用进程端的启动

1.startActivity()最终调用的是startActivityForResult()

           这个方法内部有个mParent的空判断,这个mParent是个ActivityGroup,在Activity嵌套Activity的情况下才不为空,

    但这个已经在API13的时候就废弃掉了,改用了Fragment。所以我们只管mParent为空的条件下的逻辑即可。

2.startActivityForResult()内部接着调用了InstrumentationexecStartActivity()

          这个方法的第二个参数是mMainThread.getApplicationThread(),核心功能都在这个ApplicationThread中完成;

3.接着又调用ActivityManagerNative.getDefault().startActivity()

         第一个参数whoThreadIApplicationThread的实例,它的实现类是ApplicationThread,

         启动Activity的核心功能由其内部的scheduleLaunchActivity方法来完成;

         它们的关系是:ApplicationThread继承了ApplicationThreadNativeApplicationThreadNative又继承了Binder

   并实现了IApplicationThread接口。所以ApplicationThread也是Binder的实现类。

         这里的ActivityManagerNativeActivityManagerService在应用进程的一个client(涉及到Binder机制),通过它可以调用      ActivityManagerService的方法。

         ActivityManagerNative.getDefault().startActivity();最终会调用ActivityManagerService的startActivity,

         此时便进入SystemServer服务进程端的启动

SystemServer服务进程端的启动

系统服务端启动流程调用的方法特别多,大概的流程就是:

先对栈顶Activity执行onPause方法,而这个方法首先判断需要启动的Activity所属的进程是否已经启动,若已经启动则直接调用启动Activity的方法,否则将先启动Activity的应用进程,然后在启动该Activity。

我们主要看几个关键的方法:

1.ActivityStack.startPausingLocked()

执行栈顶Activity的onPause方法,其内部调用了prev.app.thread.schedulePauseActivity();这个prev.app.thread是IAppicationThread类型的对象;实际上这里是通过Binder机制调用ActivityThread中的ApplicationThread的schedulePauseActivity方法;

2.ActivityManagerNative.getDefault().activityPaused(token)

逻辑跟上面的ActivityManagerNative.getDefault().startActivity()一样:ActivityManagerNative作为Binder Client ,AMS作为Binder server,只不过这里是通知AMS上一个Activity已经pause了,可以启动下一个Activity了。这句话最终会调用ActivityManagerService的activityPaused方法;

3.ActivityStack.startSpecificActivityLocked()

这个方法首先会判断一下需要启动的Activity所需要的应用进程是否已经启动,若启动的话,则直接调用realStartAtivityLocked方法,否则调用startProcessLocked方法,用于启动应用进程。

启动新进程时调用了Zygote并通过socket通信的方式让Zygote进程fork出了一个新的进程,并根据我们刚刚传递的”android.app.ActivityThread”字符串,反射出该对象并执行ActivityThread的main方法。这样我们所要启动的应用进程这时候其实已经启动了,但是还没有执行相应的初始化操作。

其实,前一个Activity执行pause的过程中,也涉及到Binder机制,上面我们提到:ActivityManagerNative作为Binder Client调用ActivityManagerService也就是Binder server实现了应用进程与SystemServer进程的通讯;而此时IAppicationThread作为Binder Client调用ActivityThread中的ApplicationThread。也就是Binder server实现了SystemServer进程与应用进程的通讯。

经过一系列的方法调用,最终执行到ActivityThread的scheduleLauncherActivity方法,在这个方法内部构造了一个Activity记录——ActivityClientRecord,此时,启动流程又从SystemServer服务进程端再次回到了应用进程端。

大致流程

ActivityThread接收到SystemServer进程的消息之后会通过其内部的Handler对象分发消息,经过一系列的分发之后调用了ActivityThread的handleLaunchActivity方法,接着又调用了performLauncherActivity方法,这个方法最终返回了一个Activity,也就是说我们需要的Activity对象终于创建出来了,而且是以反射的机制创建的。

具体流程

1.IApplicationThread.scheduleLauncherActivity()

其实这里真正执行的是ActivityThread中的scheduleLauncherActivity(),在这个方法内部构造了一个Activity记录——ActivityClientRecord;

2.ActivityThread.sendMessage() 

ActivityThread通过其内部的Handler对象分发消息

3.ActivityThread.handleLauncherActivity() 

4.ActivityThread.performLauncherActivity()

这个方法真正构造了一个Activity

performLauncherActivity内部调用了mInstrumentation.newActivity(),用ClassLoader(类加载器)将目标activity的类通过类名加载进来并调用newInstance来实例化一个对象,其实就是通过Activity的无参构造方法来new一个对象,对象就是在这里new出来的。然后调用Instrumentation的callActivityOnCreate方法,最终执行activity的performCreate方法,目标activity的onCreate就被调用了,到此为止,Activity被启动了,接下来的流程就是Activity的生命周期了。

标签:调用,启动,概念分析,流程,ActivityThread,Activity,进程,方法
来源: https://blog.csdn.net/S_Alics/article/details/98059621