Activity启动流程(Api29)

启动一个Activity的方法:创建Intent,调用Context.startActivity传入这个Intent对象。

Context的startActivity是一个抽象方法,由Activity和ContextWrapper实现,ContextWrapper是交给内部的Context对象mBase。

先直接看Activity.startActivity的实现:
startActivity是直接调用的startActivityForResult()

//#startActivityForResult()
if(mParent == null){
    Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
}else{
  Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, child,
                intent, requestCode, options);
                   }

不管有没有Activity mParent对象,都走了Instrumentation的execStartActivity方法。
execStartActivity方法中走了 ActivityTaskManager.getService().startActivity()

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

ActivityTaskManager.getService()返回了一个IActivityTaskManager,这里用到了IPC,真正的实现是ActivityTaskManagerService,最后调用的是

getActivityStartController().obtainStarter(intent,"startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId) //这里调用后ActivityStarter的mayWait置为true
                .execute();

在看ActivityStarter的execute()方法,这里因为mayWait == true,所以这里调用了startActivityMayWait()

然后依次调用

->startActivityMayWait()

->startActivity() Lline1288->566

->startActivity() Lline583->611(new出来了一个ActivityRecord,传递下去Line899)

->startActivity() Lline933->1386

->startActivityUnchecked() Lline1394->1464

。。。。。。
//这里去获取当前显示的这个Activity的ActivityRecord,处理一些栈信息(reusedActivity.getTaskRecord())、Flags等
 ActivityRecord reusedActivity = getReusableIntentActivity();
。。。。。。
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
        mOptions);
。。。。。。
mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);

->这里就调用到了ActivityStack的startActivityLocked()以及ensureActivitiesVisibleLocked()方法,进入ActivityStack

  • makeVisibleAndRestartIfNeeded

  • mStackSupervisor.startSpecificActivityLocked(next, true, false);

最终走到了ActivityStackSupervisor(ActivityRecord的管理类)的startSpecificActivityLocked()

final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
            //热启动
。。。。。。
 realStartActivityLocked(r, wpc, andResume, checkConfig);
。。。。。。
}else{
            //冷启动
}

判断冷启动还是热启动
wpc.hasThread()是判断IApplicationThread是否存在

IApplicationThread就是ActivityThread中的内部类ApplicationThread,这里也是一个IPC

热启动

realStartActivityLocked继续往下看,这个防范里面可以看到一个WindowProcessController类,这个类里面维护了当前进程的所有的ActivityRecord(mActivities)以及ApplicationInfo等

  //realStartActivityLocked()
   final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

  final DisplayContent dc = r.getDisplay().mDisplayContent;
  clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                r.assistToken));
  // Line853
  mService.getLifecycleManager().scheduleTransaction(clientTransaction); 

scheduleTransaction方法:

  void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }

走到了ClientTransaction.schedule(),看下ClientTransaction类

    private IApplicationThread mClient;
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

mClient对象就是IApplicationThread,前面我们说过IApplicationThread的实现就是ActivityThread内部的ApplicationThread我们回到ActivityThread里面看下:

   @Override
       public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
           ActivityThread.this.scheduleTransaction(transaction);
       }

再看下ActivityThread的scheduleTransaction方法,这个方法是在它的父类ClientTransactionHandler里面实现的

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

又回到了ClientTralpansaction里面:

   //ClientTransaction.java
    public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
        if (mActivityCallbacks != null) {
            final int size = mActivityCallbacks.size();
            for (int i = 0; i < size; ++i) {
               //关键看这里,这里执行mActivityCallbacks的preExecute,前面我们知道在realStartActivityLocked()方法执行的时候ClientTransaction通过这个字段塞了一个LaunchActivityItem进来
                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
            }
        }
        if (mLifecycleStateRequest != null) {
            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
        }
    }
    //LaunchActivityItem.java
    @Override
    public void preExecute(ClientTransactionHandler client, IBinder token) {
        client.countLaunchingActivities(1);
        client.updateProcessState(mProcState, false);
        client.updatePendingConfiguration(mCurConfig);
    }

上下文可知,ClientTransactionHandler实际上就是ActivityThread,但是问题来了,点进去看对应的方法,还是没看到怎么创建的Activity,难道方向错了?
在LaunchActivityItem的preExecute方法下面,还有一个execute方法,里面有调用ActivityThread.handleLaunchActivity()

    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client, mAssistToken);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

这个看起来更像啊,那会不会是走了这个方法,怎么走到的呢?回到ClientTransactionHandler的scheduleTransaction()方法:

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

我们看下第二行,看着应该是通过Handle发送可以一个ActivityThread.H.EXECUTE_TRANSACTION类型的消息,并且携带了transaction,事实上也确实如此,sendMessage的实现还是在ActivityThread里面。直接看下处理这个消息的地方:

 //ActivityThread.java Line2014
 case EXECUTE_TRANSACTION:
                    //取出了ClientTransaction
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    //重点在这里
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;

mTransactionExecutor是TransactionExecutor的对象,看它的execute方法:

//TransactionExecutor.java #execute()
 public void execute(ClientTransaction transaction) {
       。。。。。。
        executeCallbacks(transaction);
        。。。。。。
    }
//TransactionExecutor.java #executeCallbacks()
    public void executeCallbacks(ClientTransaction transaction) {
       。。。。。。
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            。。。。。。
           //终于找到了!!!
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
              。。。。。。
        }
   。。。。。。
    }

终于找到了,这里获取了ClientTransaction里面的callbacks,遍历得到item,在当前场景下就是LaunchActivityItem,执行LaunchActivityItem的execute方法,最终走到了ActivityThread.handleLaunchActivity()方法。

  • 接着ActivityThread.handleLaunchActivity往下走
//ActivityThread.handleLaunchActivity()  Line3409
 final Activity a = performLaunchActivity(r, customIntent);
  • ActivityThread.performLaunchActivity(ActivityClientRecord r, Intent customIntent):
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
。。。。。。
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
          。。。。。。
        } 
       。。。。。。
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (activity != null) {
                appContext.setOuterContext(activity);
                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,
                        r.assistToken);
。。。。。。
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
              。。。。。。
                r.activity = activity;
            }
            r.setState(ON_CREATE);
。。。。。。

        } catch (SuperNotCalledException e) {
         。。。。。。
        } catch (Exception e) {
          。。。。。。
        }

        return activity;
    }

这个方法会调用Instrumentation.newActivity(ClassLoader cl, String className,
Intent intent)使用类加载器创建Activity对象(调用newActivity之前会先调用makeApplication方法,在需要Application的时候创建,比如当前Activity在一个全新的进程,需要创建新的Application),并且调用Activity.attach方法,然后调用Instrumentation.callActivityOnCreate()
至此,我们的Activity创建好了

中间出现过几个需要注意的类,注意下几者的关系:
  • ActivityRecord:一个Activity的所有信息
  • TaskRecord:栈内信息,内部维护ArrayList<ActivityRecord>用来保存这个栈对应的所有的ActivityRecord
  • ActivityStack:一个应用的所有栈信息,内部维护了ArrayList<TaskRecord>,用来管理所有的TaskRecord。
  • ActivityStackSupervisor
冷启动:

冷启动也会去走Activity的启动流程,但是会多做下面创建新的进程的流程

// Post message to start process to avoid possible deadlock of calling into AMS with the
            // ATMS lock held.
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);

这里通过Handle处理,我们先看 mService.mH的handleMessage方法

  @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case REPORT_TIME_TRACKER_MSG: {
                    AppTimeTracker tracker = (AppTimeTracker) msg.obj;
                    tracker.deliverResult(mContext);
                } break;
            }
        }

没发现什么相关处理,再回头看构建的这个Message

//PooledLambda.java #obtainMessage()
 static <A, B, C, D, E, F> Message obtainMessage(
            HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
            A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
        synchronized (Message.sPoolSync) {
            PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                    function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
                    null);
            return Message.obtain().setCallback(callback.recycleOnUse());
        }
    }

PooledLambda的obtainMessage方法会把ActivityManagerInternal::startProcess这个方法丢到Message的callback,我们知道handle的callback会在收到message的时候执行,所以最后走的是ActivityManagerInternal::startProcess,这个方法如何通过function和args构建出来在PooledLambdaImpl.acquire()方法里,这里不去分析了。

直接看ActivityManagerInternal.startProcess(),发现这是一个抽象方法,那么实现是谁呢?

ActivityManagerInternal类上有一行注释:

Activity manager local system service interface.

那肯定和ActivityManagerService有关系啊,转而看到ActivityManagerService里面有个内部类LocalService,它继承了ActivityManagerInternal,startProcess的实现如下

//ActivityManagerService.LocalService #startProcess()
 @Override
        public void startProcess(String processName, ApplicationInfo info,
                boolean knownToBeDead, String hostingType, ComponentName hostingName) {
            try {
                。。。。。。
                synchronized (ActivityManagerService.this) {
                    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                            new HostingRecord(hostingType, hostingName),
                            false /* allowWhileBooting */, false /* isolated */,
                            true /* keepIfLarge */);
                }
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
        }

哦吼,调用到ActivityManagerService的startProcessLocked(),

->PrcessList.startProcessLocked()

->startProcess()

->这里进入AppZygote

final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

startResult = appZygote.getProcess().start

->startViaZygote()

->zygoteSendArgsAndGetResult() //开启了一个socket用来同信

进入ZygoteInit

main方法

//从这里开启了 SystemServer进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
//等待ActivityManagerService的请求
zygoteServer.runSelectLoop(abiList);

forkSystemServer中调用了handleSystemServerProcess()又调用到了 ZygoteInit.zygoteInit(),最后调用 RuntimeInit.applicationInit()

RuntimeInit.applicationInit()调用findStaticMain利用反射调用ActivityThread的main方法。

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

推荐阅读更多精彩内容