Activity启动流程(一)——基于Android11分析

我们分析一下Activity的启动流程,源码是基于Android 11

1、Activity 中的逻辑

Activity.java core\java\android\app

Activity 继承自 context,重写了startActivity
看出startActivity(Intent intent) 是直接调用的startActivity(Intent intent, @Nullable Bundle options)
然后一层一层调用进去,不断判断逻辑,增加参数,最后是调用Activity 成员mInstrumentation 的 execStartActivity对象

    /**
     * Same as {@link #startActivity(Intent, Bundle)} with no options
     * specified.
     *
     * @param intent The intent to start.
     *
     * @throws android.content.ActivityNotFoundException
     *
     * @see #startActivity(Intent, Bundle)
     * @see #startActivityForResult
     */
    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null); //可以看出是直接调用的下面的方法
}




    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)
                && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY)) {//规则判定,正常流程Extra不包含这些
            if (TextUtils.equals(getPackageName(),
                    intent.resolveActivity(getPackageManager()).getPackageName())) {
                // Apply Autofill restore mechanism on the started activity by startActivity()
                final IBinder token =
                        mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
                // Remove restore ability from current activity
                mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
                mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY);
                // Put restore token
                intent.putExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN, token);
                intent.putExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY, true);
            }
        }
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);//options是null,调用这里
        }
    }




    /**
     * Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
     * with no options.
     *
     * @param intent The intent to start.
     * @param requestCode If >= 0, this code will be returned in
     *                    onActivityResult() when the activity exits.
     *
     * @throws android.content.ActivityNotFoundException
     *
     * @see #startActivity
     */
    //如果request > 0,那么 会在onActivityResult里返回,传进来的是-1,不关心
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);



    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }



    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {//正常来说这里parent都会为null,走这条分支
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,//看到是调用Activity 成员mInstrumentation 的 execStartActivity对象
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(//返回回源activity
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {// 为 -1,不走这
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {//走不进来
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }


2、Instrumentation中的逻辑

Instrumentation.java core\java\android\app

instrumentation是Android系统里面的一套控制方法或者”钩子“。这些钩子可以在正常的生命周期(正常是由操作系统控制的)之外控制Android控件的运行,其实指的就是Instrumentation类提供的各种流程控制方法。
它内部有一个 ActivityThread 的引用,可以操作Activity 的生命周期,控件,行为等,一般用于android 应用测试框架中。

先分析它的参数

contextThread

  1. who: 源Activity
  2. contextThread: 源应用程序的ApplicationThread
  3. token: Activity 的成员 mToken
  4. target: 源Activity,同 who
  5. intent: 传进来的intent
  6. requestCode: -1
  7. options: null

.
简单介绍一些它的行为,就是通过ATM的静态方法getService获取到ATMS的代理端,然后通过代理端来调用startActivity,这样就相当于调用了服务端ATMS 的startActivity



    @UnsupportedAppUsage
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;//whoThread 是源目标的 ApplicationThread,这里还原下类型
        Uri referrer = target != null ? target.onProvideReferrer() : null;//返回是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= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData(who);//对intent中的数据做一些处理
            intent.prepareToLeaveProcess(who);//根据当前who和intent的包名来判断是否需要启动新的进程,如果是的话,进行一些准备工作
            int result = ActivityTaskManager.getService().startActivity(whoThread,//通过ATMS的静态方法getService获取到ATMS的代理端,然后调用startActivity
                    who.getBasePackageName(), who.getAttributionTag(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                    target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

2、ATM中的逻辑

ActivityTaskManager.java core\java\android\app

ATM 是个普通类, getService 返回 IActivityTaskManager 类型的IBinder对象,往下看,可以看出这里是一个通过泛型巧妙设计的单例。

     /** @hide */
    public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }

    @UnsupportedAppUsage(trackingBug = 129726065)
    private static final Singleton IActivityTaskManagerSingleton =
            new Singleton() {
                @Override
                protected IActivityTaskManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);//可以看出这里也是通过ServiceManager获得代理端
                    return IActivityTaskManager.Stub.asInterface(b);//转换成IActivityTaskManager 类型的 Interface 返回
                }
            };


public abstract class Singleton {

    @UnsupportedAppUsage
    public Singleton() {
    }

    @UnsupportedAppUsage
    private T mInstance;

    protected abstract T create();

    @UnsupportedAppUsage
    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

咱们直接看它的服务端实现吧

2、ATMS中的逻辑

ActivityTaskManagerService.java services\core\java\com\android\server\wm

ATMS 是 ATM 的服务端,全面负责Activity

这里是顺序执行了
startActivity——>startActivityAsUser——>startActivityAsUser——>getActivityStartController().obtainStarter().execute()

最后通过getActivityStartController() 获得内部的成员 mActivityStartController,这里通过工厂方法来构建ActivityStarter,然后执行构造。

参数太多不好看,我们先分析上面Instrumentation 传进来的参数

who: 源目标的 ApplicationThread
callingPackage: who.getBasePackageName
callingFeatureId: callingFeatureId ApplicationThread 成员, 调用特征id
intent: intent
resolvedType: intent.resolveTypeIfNeeded(who.getContentResolver())查看Intent里是否有MIME或者Uri
token: 源Activity 的成员 mToken
resultWho: target.mEmbeddedID target是源Activity,同 who
requestCode: -1
startFlags: 0
profilerInfo: null
options: null


    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());//就加了个 UserHandle.getCallingUserId()
}




    @Override
    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);// 就加了个true 验证传入用户
    }

    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        assertPackageMatchesCallingUid(callingPackage);//检测包名和UID是否匹配
        enforceNotIsolatedCaller("startActivityAsUser");//判断是否隔离

        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")// 这里是一个巧妙地工厂方法
                .setCaller(caller)//调用方的AppThread的IBinder
                .setCallingPackage(callingPackage)//调用方的包名
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)//调用者的类型type
                .setResultTo(resultTo)//调用方的ActivityClientRecord的binder(实际上是AMS的ActivityRecord对应在App端的binder对象)
                .setResultWho(resultWho)//调用方的标识
                .setRequestCode(requestCode)// 需要返回的requestCode 这里是-1
                .setStartFlags(startFlags)//启动标志位
                .setProfilerInfo(profilerInfo)//启动时带上的权限文件对象,这里为Null
                .setActivityOptions(bOptions)//null
                .setUserId(userId)
                .execute();//最后执行
}

2、ActivityStarter 和 ActivityStartController中的逻辑

ActivityStartController.java services\core\java\com\android\server\wm

这里只是返回一个带有初级参数的ActivityStarter

    /**
     * @return A starter to configure and execute starting an activity. It is valid until after
     *         {@link ActivityStarter#execute} is invoked. At that point, the starter should be
     *         considered invalid and no longer modified or used.
     */
    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }
ActivityStarter.java services\core\java\com\android\server\wm

看到这里好难受啊,为了把流程走完,先只分析重点吧,害

你可能感兴趣的:(Activity启动流程(一)——基于Android11分析)