Activity的工作过程你造吗?

作者: 卡路fly | 来源:发表于2017-04-18 09:33 被阅读266次

我们都知道activity使用<code>startActivity</code>启动,那么startActivity又是如何进行的呢?

1. startActivity有多种重载方式,但是最终都会调用<code>startActivityForResult</code>方法。

  • 注意<code>mMainThread.getApplicationThread()</code>这个参数,类型为ApplicationThread
  • <code>ApplicationThread</code>是<code>ActivityThread</code>的一个内部类。

2. <code>startActivityForResult</code>内部是调用了<code>Instrumentation</code>的<code>execStartActivity</code>

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                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++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent); // 检查启动activity的结果
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
  • 启动Activity的真正实现,<code>ActivityManagerNative.getDefault()</code>的startActivity方法完成。


  • ActivityManagerService(<code>AMS</code>)继承自<code>ActivityManagerNative</code>
    ActivityManagerNative继承自<code>Binder</code>实现了<code>IActivityManager</code>的Binder接口
    所以,AMS也是一个Binder,是<code>IActivityManager</code>的具体实现
    <code>ActivityManagerNative.getDefault()</code>的具体实现是AMS

  • AMS这个Binder对象使用单例模式对外提供,Singleton是一个单例的封装类,第一次调用<code>get</code>方法会通过<code>create</code>进行初始化AMS的Binder对象,后续调用中直接返回之前的对象。

3.转移至<code>AMS</code>中的<code>startActivity</code>方法

4.转移至<code>ActivityStackSupervisor</code>中的<code>startActivityMayWait</code>方法

从Intent里解析需要启动的Activity的相关信息。如:包名、类名。相关信息存在ResolveInfo类中,通过该类里面得到ActivityInfo对象。

5.转移至<code>ActivityStackSupervisor.startActivityLocked</code>方法

通过传入的caller形参(IApplicationThread类型,从Activity的startActivity函数就开始一个个函数调用传入)得到调用者进程相关信息,保存到callerApp(ProcessRecord类型)变量中,然后创建要启动的Activity相关信息。保存到r(ActivityRecord)变量中。

6.转移至<code>ActivityStackSupervisor.startActivityUncheckedLocked</code>方法

获取Activity的启动模式、判断要启动的Activity是否在栈顶、得到Activity加载的栈。

7.转移至<code>ActivityStack.resumeTopActivitiesLocked</code>方法

确保被调用的Activity所在的栈处于顶端。

8.转移至<code>ActivityStack.resumeTopActivityInnerLocked</code>方法

判断要启动的Activity所在的栈是否对当前用户不可见,如果不可见就不需要继续执行下去,因为即使把这个Activity启动起来,用户也看不见,还不如先把它保存起来,等到下次可见的时候再启动。若可见,则继续执行。把要启动的Activity添加到栈顶。

9.转移至<code>ActivityStackSupervisor.startSpecificActivityLocked</code>方法

主要跟要启动的Activity进程相关。如判断所再进程是否已经运行、判断是否另开进程。如果没有指定新进程,即直接用默认进程,则直接调用realStartActivityLocked。

10.转移至<code>ActivityStackSupervisor.realStartActivityLocked</code>方法

  • 通过Binder驱动进入到ApplicationThread的<code>scheduleLaunchActivity</code>函数。
4-10示意图
  • <code>ApplicationThread</code>继承自<code>ApplicationThreadNative</code>

  • <code>ApplicationThreadNative</code>继承自Binder实现了<code>IApplicationThread</code>接口。

    • ApplicationThreadNative和系统为AIDL文件生成的类是一样的。
    • ApplicationThreadNative内部有一个<code>ApplicationThreadProxy</code>类,也是系统为AIDL文件自动生成的代理类。
  • <code>ApplicationThreadNative</code>是<code>IApplicationThread</code>的实现者,因为<code>ApplicationThreadNative</code>被系统定义为抽象类,所以<code>ApplicationThread</code>是<code>IApplicationThread</code>的实现者。

11.转移至<code>ApplicationThread</code>中通过<code>scheduleLaunchActivity</code>来启动Activity

  • 在ApplicationThread中,<code>scheduleLaunchActivity</code>通过发送一个启动acitivity的消息交给Handler,这个Handler名字:H。

  • sendMessage作用发送一个消息给H处理。

12.启动Activity的过程由<code>ActivityThread</code>的<code>handleLaunchActivity</code>方法来实现。

<code>performLaunchActivity</code>主要完成

  1. 从<code>performLaunchActivity</code>中获取待启动的Activity的组件信息。
  2. 通过<code>Instrumentation</code>的<code>newActivity</code>方法使用类加载器创建Activity对象。
  3. 通过<code>LoadedApk</code>的<code>makeApplication</code>方法尝试创建Application对象。
  4. 创建<code>ContextImpl</code>对象,并通过Activity的<code>attach</code>方法完成一些重要数据的初始化。
  5. 调用Activity的onCreate方法

13.ActivityThread通过<code>handleResumdeActivity</code>方法来调用被启动Activity的onResume生命周期方法。


启动App

  • AMS组织回退栈时以<code>ActivityRecord</code>为基本单位,所有的ActivityRecord放在同一个<code>ArrayList</code>里,可以将mHistory看作一个栈对象,索引0所指的对象位于栈底,索引mHistory.size()-1所指的对象位于栈顶
  • Zygote进程孵化出新的应用进程后,会执行<code>ActivityThread</code>类的<code>main</code>方法.在该方法里会先准备好<code>Looper</code>和消息队列,然后调用<code>attach</code>方法将应用进程绑定到<code>AMS</code>,然后进入<code>looper</code>循环,不断地读取消息队列里的消息,并分发消息。
  • AMS应用进程已启动,AMS保存应用进程的一个代理对象,这样AMS可以通过这个代理对象控制应用进程,然后<code>AMS</code>通知应用进程创建入口Activity的实例,并执行它的生命周期方法。

相关文章

网友评论

    本文标题:Activity的工作过程你造吗?

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