进程内Activity启动过程源码研究,基于 android api-28

废话不说,开搞。

一、StartActivity

最终是调的startActivityForResult

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
       ……
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
      ……
    }

成员变量Instrumentation的execStartActivity

    public ActivityResult execStartActivity(
        ……
        int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
        ……

ActivityManager.getService()

    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

Binder 机制 调用系统服务 ActivityManagerService,所以直接看 AMS(简写) 的startActivity

二、 来到系统进程ActivityManagerService

startActivity——startActivityAsUser

    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity");

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

        // TODO: Switch to user app stacks here.
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();

    }

mActivityStartController—— obtainStarter—— execute
点两下等于
ActivityStarter ——execute

    int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            } else {
                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            }
        } finally {
            onExecutionComplete();
        }
    }

ActivityStarter ——startActivityMayWait

    private int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
            int userId, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {

            ……

            int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                    allowPendingRemoteAnimationRegistryLookup);
          ……

ActivityStarter ——startActivity 注意这里有好几层

    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
            ……
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
            ……
        return result;
    }

ActivityStarter ——startActivityUnchecked 这里面不知道怎么找了 百度了一下别人的

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
……
             mSupervisor.resumeFocusedStackTopActivityLocked();
……

ActivityStackSupervisor ——resumeFocusedStackTopActivityLocked

    boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
    }

    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

        if (!readyToResume()) {
            return false;
        }

        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || !r.isState(RESUMED)) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.isState(RESUMED)) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }

        return false;
    }

ActivityStack ——resumeTopActivityUncheckedLocked

 result = resumeTopActivityInnerLocked(prev, options);

ActivityStack ——resumeTopActivityInnerLocked 真长

mStackSupervisor.startSpecificActivityLocked(next, true, true);

ActivityStackSupervisor ——startSpecificActivityLocked

realStartActivityLocked(r, app, andResume, checkConfig);

ActivityStackSupervisor ——realStartActivityLocked

然后这里秀了我一脸,大爷的差点没 neng 晕我!!!!

因为 api-28 之前 直接就是app.thread.scheduleLaunchActivity 进入 ApplicationThread,然而 api-28好像用了某种 我目前还不太了解的设计模式,什么Transaction记录后期学习下。

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            ……
            //已屏蔽 无关代码 和参数
             final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
              clientTransaction.addCallback(LaunchActivityItem.obtain(……),……);

               // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
      

比较重要的ClientTransaction,LaunchActivityItem,ResumeActivityItem,mService就是ActivityManagerService。

这行代码:
mService.getLifecycleManager().scheduleTransaction(clientTransaction);

ActivityManagerService的getLifecycleManager

    ClientLifecycleManager getLifecycleManager() {
        return mLifecycleManager;
    }

mLifecycleManager是ClientLifecycleManager

class ClientLifecycleManager {
    
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            transaction.recycle();
        }

ClientTransaction——schedule, ClientTransaction在上面realStartActivityLocked初始化的

public class ClientTransaction implements Parcelable, ObjectPoolItem {
    private IApplicationThread mClient;
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

mClient就是ClientTransaction在上面realStartActivityLocked初始化时候 app.thread。
变量app是一个ProcessRecord对象,它的成员变量thread是IApplicationThread类型,因此app.thread是IApplicationThread,一猜就是某个服务的代理对象,又要用 Binder 机制了;

IApplicationThread 服务端实体是 ApplicationThread类。
所以这里又一次 通过 Binder 机制,交给了ApplicationThread的scheduleTransaction方法。

三、交给ApplicationThread

ApplicationThread原来是 ActivityThread 的内部类,我说怎么搜了半天也没有。
看继承关系

public final class ActivityThread extends ClientTransactionHandler {
        private class ApplicationThread extends IApplicationThread.Stub {
               @Override
              public void scheduleTransaction(ClientTransaction transaction) throws         
                     RemoteException {
                  ActivityThread.this.scheduleTransaction(transaction);
              }
        }
}

ActivityThread里没有scheduleTransaction,原来在他爹ClientTransactionHandler里

public abstract class ClientTransactionHandler {

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

用 Handler讲transaction发给了ActivityThread的 H:

class H extends Handler {
      public void handleMessage(Message msg) {
            case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {                      
                         transaction.recycle();
                    }
                    break;
      }
}

mTransactionExecutor是TransactionExecutor类
TransactionExecutor——execute


 public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
    }

  public void executeCallbacks(ClientTransaction transaction) {
      final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
      ……
      for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            ……
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
      }
  }

   private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        ……
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
   }

循环ClientTransaction里所有的 ClientTransactionItem与ActivityLifecycleItem并执行execute。
那么这俩ClientTransactionItem与ActivityLifecycleItem啥呢,就是上面realStartActivityLocked里说的比较重要的LaunchActivityItem,ResumeActivityItem啥的。
LaunchActivityItem:

public class LaunchActivityItem extends ClientTransactionItem {
     @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        ……
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        ……
    }
}

client就是 ActivityThread 所以就执行ActivityThread的handleLaunchActivity。

ResumeActivityItem跟 Activity 创建启动没事关系,我只是后来找生命周期 onStart, onResume怎么也找不到,百度也没有讲 api-28 的源码。所以这里剧透下onStart, onResume是在ResumeActivityItem的execute执行的。

ActivityThread——handleLaunchActivity

    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
          ……
          final Activity a = performLaunchActivity(r, customIntent);
          ……

ActivityThread——performLaunchActivity

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //获取组件信息
         ContextImpl appContext = createBaseContextForActivity(r);
                ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }
        //创建 Context
        ContextImpl appContext = createBaseContextForActivity(r);
        //创建 Activity
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
           ……
        } catch (Exception e) {
           ……
        }

       try {
             //创建Application
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
              
            //并和activity  attach
             activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);

           //启动 Activity 里面最终调了 onCreate
            if (r.isPersistable()) {
                   mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                   mInstrumentation.callActivityOnCreate(activity, r.state);
       }
    }

ActivityThread$performLaunchActivity方法的操作:

1,获取要启动的Activity的ComponentName对象:里面包含了包名,类名相关的信息;
2,创建Activity的上下文环境:即创建了ContextImpl对象;
3,创建Activity的实例:调用Instrumentation的newActivity方法,并使用类加载器创建Activity对象;
4,创建Application对象;
5,调用Activity的attach方法:初始化Activity类里的一些数据;
6,启动Activity:调用Instrumentation$callActivityOnCreate方法;

Instrumentation——newActivity:

    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        String pkg = intent != null && intent.getComponent() != null
                ? intent.getComponent().getPackageName() : null;
        return getFactory(pkg).instantiateActivity(cl, className, intent);
    }

至此 Activity 与其所需的 Application 、Comtext 初始化完成。

四、生命周期

接上面
mInstrumentation.callActivityOnCreate:

activity.performCreate(icicle, persistentState);

Activity——performCreate

    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
       ……
    }

ok 调用了 onCreate。
然后 onStart,onResume 都在
ResumeActivityItem—— ActivityThread .handleResumeActivity——ActivityThread.performResumeActivity—— Activity.performResume:

    final void performResume(boolean followedByPause, String reason) {
        performRestart(true /* start */, reason);
          ……
        // mResumed is set by the instrumentation
        mInstrumentation.callActivityOnResume(this);

performRestart:

mInstrumentation.callActivityOnRestart(this);

Instrumentation:

    public void callActivityOnRestart(Activity activity) {
        activity.onRestart();
    }
  
    public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();
    ……
    }

ok,完毕!

五、总结

进程内 startActivity 启动 Activity
首先调用Activity的startActivityForResult;
然后是mInstrumentation.execStartActivity,Instrumentation通过 Binder 机制将任务交给ActivityManagerService;
ActivityManagerService做了一系列准备工作后,通过 Binder 机制将任务交给 ApplicationThread;
ApplicationThread为 ActivityThread 的内部类,直接把启动任务交于ActivityThread;ActivityThread通过handler 将任务发给 内部Handler H最终执行自己的performLaunchActivity,
并在此方法创建Activity ,以及其所需的 Context、组件信息、与Application 的 attach,生命周期方法 onCreate 的执行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容