美文网首页
Android 组件--Activity 启动流程(9.0)

Android 组件--Activity 启动流程(9.0)

作者: android_coder | 来源:发表于2018-11-17 17:53 被阅读0次

本文基于Android 9.0讲解下Activity的启动流程
Activity启动流程大致分为20几步

1:Activity的startActivity

public void startActivity(Intent intent, @Nullable Bundle options) {
    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);
    }
}

2:startActivityForResult

public void startActivityForResult(
        String who, Intent intent, int requestCode, @Nullable Bundle options) {
    Uri referrer = onProvideReferrer();
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    options = transferSpringboardActivityOptions(options);
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, who,
            intent, requestCode, options);
    if (ar != null) {
        mMainThread.sendActivityResult(
            mToken, who, requestCode,
            ar.getResultCode(), ar.getResultData());
    }
    cancelInputsAndStartExitTransition(options);

}

3:Instrumentation执行execStartActivity

try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .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的启动结果,譬如当activity没有在配置文件中注册的时候会报; have you declared this activity in your AndroidManifest.xml?"
四大组件的解析都是通过PackageParser这个工具类来解析的,构建一个ActivityInfo,ServiceInfo,ProviderInfo信息,如果ActivityInfo等为空的话,并且intent传递的组件compent不为空,那么就会抛出异常

4:进入到AMS的startActivity方法

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

根据用户id来启动activity,有多用户的概念,这是一个跨进程的过程

5:继续调用同名的方法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是一个ActivityStartController对象,其调用了obtainStarter方法来获取一个ActivityStarter对象,从而启动任务交给了ActivityStarter

6: 进入到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();
        }
    }

由于我们在AMS的startActivityAsUser中调用了setMayWait方法,也就是ActivityStarter的setMayWait方法,所以第一个if判断条件满足

    ActivityStarter setMayWait(int userId) {
        mRequest.mayWait = true;
        mRequest.userId = userId;

        return this;
    }

7:进入ActivityStarter的startActivityMayWait方法

该方法有三个比较重要的信息点
1:解析intent信息构建一个ResolveInfo
2:根据ResolveInfo信息构建一个ActivityInfo信息
3: 调用startActivity方法返回启动结果

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);

ResolveInfo和ActivityInfo均是通过调用PackageParser的相关方法解析得到的信息

8:startActivity方法

该方法会继续调用同名的startActivity方法

9:同名的startActivity方法

这个方法里面主要做了几件事情
1:获取启动该activity的进程ProcessRecord,如果该进程caller为空,那么就认为没有权限启动该activity,返回的错误码是err = ActivityManager.START_PERMISSION_DENIED;也就是没有权限启动
2: 获取调用者activityRecord,ActivityRecord在system_server代表一个activity对象

    ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
            sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                    "Will send result to " + resultTo + " " + sourceRecord);
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }

3:错误判断

       if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
            // We couldn't find a class that can handle the given Intent.
            // That's the end of that!
            err = ActivityManager.START_INTENT_NOT_RESOLVED;
        }

        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
            // We couldn't find the specific class specified in the Intent.
            // Also the end of the line.
            err = ActivityManager.START_CLASS_NOT_FOUND;
        }

如果无法解析出compent或是aInfo为空则返回对应的错误码
4:构建出ams端的一个activityrecord对象

ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, checkedOptions, sourceRecord);

上面的callingpid,callinguid在此处有体现

10:继续执行同名的startActivity方法

mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);

11:执行startActivityUnchecked

1:主要是计算启动activity的flag

  computeLaunchingTaskFlags();
  computeSourceStack();

2: 获取是否有可以复用的activity

  ActivityRecord reusedActivity = getReusableIntentActivity();

3: 如果存在可以复用的activity,那么则复用该activity,并且回调onnnewintent方法

deliverNewIntent(top);

4:判断是否需要重新创建一个task,如果带有new_task_flag那么就会创建一个新的task
5: 调用ActivityStatck的mTargetStack.startActivityLocked方法

12:ActivityStack的startActivityLocked

1:向wms添加token值

     if (r.getWindowContainerController() == null) {
            r.createWindowContainer();
        }

2:调整activity在task中的位置,将其放在顶部
这个方法主要是如果创建了新的task那么将新的task至于Stack的前台,如果没有新建task那么则插入到task的顶部

insertTaskAtTop(rTask, r);

3:准备activity的切换动画

mWindowManager.prepareAppTransition(transit, keepCurTransition);

4:添加一个启动窗口

r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));

13:调用resumeFocusedStackTopActivityLocked

14:调用targetStack.resumeTopActivityUncheckedLocked

15:resumeTopActivityInnerLocked

1:先暂停处于resumed状态的activity

pausing |= startPausingLocked(userLeaving, false, next, false);

2: 启动下一个activity

mStackSupervisor.startSpecificActivityLocked(next, true, true);

3: 将该activity组件的状态设置成非stopped状态

16:startSpecificActivityLocked

1:设置activity的启动时间

getLaunchTimeTracker().setLaunchTime(r);

2:判断进程是否存在,如果存在则直接启动activity

  realStartActivityLocked(r, app, andResume, checkConfig);

否则构造fork一个新的进程

17:假设进程存在,创建一个activity启动的事物ClientTransaction

1:添加一个回调

clientTransaction.addCallback,

参数是ClientTransactionItem类型的,其中有一个方法execute,会构建一个activityclientrecord对象,并且调用ClientTransactionHandler的handleLaunchActivity方法
2:开始执行回调

mService.getLifecycleManager().scheduleTransaction(clientTransaction)

调用的是ClientLifecycleManager的方法

transaction.schedule();进一步调用的是ClientTraction的schedule方法
public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
}

此处的mclient是一个private IApplicationThread mClient;
进入到了app进程

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

由于class ActivityThread extends ClientTransactionHandler继承的是ClientTransactionHandler对象,那么调用的是父类的

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

18:发送一个消息到ActivityThread的主线程

sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);

这个方法的实现在子类ActivityThread中
19:对消息的处理

       case EXECUTE_TRANSACTION:
                    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;

进而执行execute方法
20:mTransactionExecutor的execute方法的执行
也就是TransactionExecutor的execute方法

    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }

21:executeLifecycleState方法的调用

lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);

lifecycleItem 是ActivityLifecycleItem类型的对象
而ActivityLifecycleItem是一个抽象类
会调用两个关键的方法

executeCallbacks(transaction);
executeLifecycleState(transaction);

1:executeCallbacks,会调用item的excute方法

item.execute(mTransactionHandler, token, mPendingActions);

这个item是从list数组中取出来的

final ClientTransactionItem item = callbacks.get(i);

添加的位置在ActivityStackSuperVisor的realStartActivity方法

clientTransaction.addCallback(LaunchActivityItem

其类型是LaunchActivityItem类型
22:执行LaunchActivityItem的excute方法

ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);

Client是ClientTransactionHandler类型的数据,也就是ActivityThread,进入执行到ActivityThread的handleLaunchActivity方法

23:ActivityThread的handleLaunchActivity方法

24:performLaunchActivity

主要是通过反射的机制创建一个activity对象,调用其attach方法,并且执行oncreate方法,也就是activity的oncreate方法可能被回调到,attach方法主要做了三件事情
1:关联一个context对象
2:创建phonewindow对象
3:为activity设置windowmanager对象

25:执行完成executeCallbacks方法执行executeLifecycleState方法

在执行完performLaunchActivity之后会设置其生命周期的状态值r.setState(ON_CREATE);
看看

cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

具体的实现
我们在ActivityStackSuperVisior中的realStartActivity方法中有设置我们启动activity之后期望的目标状态

    if (andResume) {
          lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
     } else {
          lifecycleItem = PauseActivityItem.obtain();
      }
     clientTransaction.setLifecycleStateRequest(lifecycleItem);

很显然我们期望的状态是Resumed状态
executeLifecycleState的入口有一个重要的方法

final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();

此时lifecycleItem对象应该是ResumeActivityItem类型的对象

cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

ResumeActivityItem的目标状态是ON_Resumed的
接下来看cycleToPath的计算
调用的是同名的cycleToPath,并且不包含最后的状态

final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);

start值的计算为
final int start = r.getLifecycleState();也就是ON_CREATE状态
finish状态值也就是ON_RESUMED状态

       if (finish >= start) {
            // just go there
            for (int i = start + 1; i <= finish; i++) {
                mLifecycleSequence.add(i);
            }
        }

根据上面的计算很显然是进入到该判断条件,也就是添加了两种状态onstart,onresume
然后执行方法

performLifecycleSequence(r, path);
     case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;

也就是回调ActivityThread的handleStartActivity和handleResumeActivity方法

26:handleStartActivity方法不需要重复说明

27:handleResumeActivity方法

该方法主要是将decorView添加到windowmanager里面,并且将窗口类型设置为
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
然后调用activity的makeVisibile方法将其设为可见状态
这样一个activity基本启动完成,后续的便是窗口的添加,relayout等其他操作

相关文章

网友评论

      本文标题:Android 组件--Activity 启动流程(9.0)

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