Android知识Android开发Android技术知识

Activity的工作过程你造吗?

2017-04-18  本文已影响266人  卡路fly

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

1. startActivity有多种重载方式,但是最终都会调用<code>startActivityForResult</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;
    }

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示意图

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

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所指的对象位于栈顶
上一篇 下一篇

猜你喜欢

热点阅读