美文网首页
UI绘制(一)——从startActivity到生命周期调用

UI绘制(一)——从startActivity到生命周期调用

作者: 王志强_9380 | 来源:发表于2019-09-26 19:31 被阅读0次
        @Override
        public void startActivity(Intent intent) {
            this.startActivity(intent, null);
        }
    
        @Override
        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); 
            }
        }
    
    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);
           //省略代码
        }
    

    这里看一下Instrumentation是什么玩意

    // set by the thread after the constructor and before onCreate(Bundle savedInstanceState) is called.
        private Instrumentation mInstrumentation;
    

    在构造函数之后,onCreate之前设置,看下设置方法在哪里

    final void attach(Context context, ActivityThread aThread,
                Instrumentation instr, IBinder token, int ident,
                Application application, Intent intent, ActivityInfo info,
                CharSequence title, Activity parent, String id,
                NonConfigurationInstances lastNonConfigurationInstances,
                Configuration config, String referrer, IVoiceInteractor voiceInteractor,
                Window window, ActivityConfigCallback activityConfigCallback) {
            //省略代码 
            mInstrumentation = instr;
            //省略代码 
        }
    

    这个attach方法在哪里调用,后面再看,直接跳到mInstrumentation.execStartActivity里看看

    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) {
                //省略代码 
                //检查是否存在这个activity, 若找到,而且处于阻塞状态,直接返回。
            }
            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);
            } catch (RemoteException e) {
                throw new RuntimeException("Failure from system", e);
            }
            return null;
        }
    

    这里来看下ActivityManager.getService().startActivity这个方法是调用到哪里(看了下7.1的是ActivityManagerNative.getDefault().startActivity,最终结果是一样的)
    首先,看看这个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;
                    }
                };
    

    这里边通过ServiceManager.getService获得了一个Binder,然后通过IActivityManager.Stub.asInterface(b)创建了一个代理,我们先看看这个Binder对象是什么玩意吧,我们搜索ACTIVITY_SERVICE这个关键字,找到在ActivityManagerService里面有这样一段代码

    public class ActivityManagerService extends IActivityManager.Stub
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback{
            public void setSystemProcess() {
            try {
                ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                        DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
    //省略代码
    }
    
    

    也就是说ServiceManager.getService(Context.ACTIVITY_SERVICE)获取到的是ActivityManagerService的Binder对象,回到上面ActivityManager.getService()
    .startActivity。这个地方调用的就是ActivityManagerService 中的方法

    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());
        }
    
        @Override
        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) {
            return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                    resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                    true /*validateIncomingUser*/);
        }
    
        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();
    
        }
    

    这句代码obtainStarter(intent, "startActivityAsUser")

        ActivityStarter obtainStarter(Intent intent, String reason) {
            return mFactory.obtain().setIntent(intent).setReason(reason);
        }
    

    进入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();
            }
        }
    
      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);
    
                //省略代码
                return res;
            }
        }
    

    最后都是调用的startActivity

      private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
                ActivityRecord[] outActivity, TaskRecord inTask, String reason,
                boolean allowPendingRemoteAnimationRegistryLookup) {
    
            if (TextUtils.isEmpty(reason)) {
                throw new IllegalArgumentException("Need to specify a reason.");
            }
            mLastStartReason = reason;
            mLastStartActivityTimeMs = System.currentTimeMillis();
            mLastStartActivityRecord[0] = null;
    
            mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                    callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                    inTask, allowPendingRemoteAnimationRegistryLookup);
    
            if (outActivity != null) {
                // mLastStartActivityRecord[0] is set in the call to startActivity above.
                outActivity[0] = mLastStartActivityRecord[0];
            }
    
            return getExternalResult(mLastStartActivityResult);
        }
    
      private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                SafeActivityOptions options,
                boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
                TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
            //省略代码
            if (err == ActivityManager.START_SUCCESS) {
                Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
                        + "} from uid " + callingUid);
            }
            //省略代码
            boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
                    inTask != null, callerApp, resultRecord, resultStack);
            //省略代码
            if (abort) {
                if (resultRecord != null) {
                    resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                            RESULT_CANCELED, null);
                }
                // We pretend to the caller that it was really started, but
                // they will just get a cancel result.
                ActivityOptions.abort(checkedOptions);
                return START_ABORTED;
            }
            //省略代码
            ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                    callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                    resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                    mSupervisor, checkedOptions, sourceRecord);
            
            //省略代码
            return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                    true /* doResume */, checkedOptions, inTask, outActivity);
        }
    

    Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
    + "} from uid " + callingUid);
    这段代码是不是很熟悉,每次启动activity我们都能在logcat里看见这个打印
    mSupervisor.checkStartAnyActivityPermission里面会去检测权限,看看里面

    boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo,
                String resultWho, int requestCode, int callingPid, int callingUid,
                String callingPackage, boolean ignoreTargetSecurity, boolean launchingInTask,
                ProcessRecord callerApp, ActivityRecord resultRecord, ActivityStack resultStack) {
            final boolean isCallerRecents = mService.getRecentTasks() != null &&
                    mService.getRecentTasks().isCallerRecents(callingUid);
            final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
                    callingUid);
            if (startAnyPerm == PERMISSION_GRANTED || (isCallerRecents && launchingInTask)) {
                // If the caller has START_ANY_ACTIVITY, ignore all checks below. In addition, if the
                // caller is the recents component and we are specifically starting an activity in an
                // existing task, then also allow the activity to be fully relaunched.
                return true;
            }
            final int componentRestriction = getComponentRestrictionForCallingPackage(
                    aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity);
            final int actionRestriction = getActionRestrictionForCallingPackage(
                    intent.getAction(), callingPackage, callingPid, callingUid);
            if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
                    || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
                if (resultRecord != null) {
                    resultStack.sendActivityResultLocked(-1,
                            resultRecord, resultWho, requestCode,
                            Activity.RESULT_CANCELED, null);
                }
                final String msg;
                if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
                    msg = "Permission Denial: starting " + intent.toString()
                            + " from " + callerApp + " (pid=" + callingPid
                            + ", uid=" + callingUid + ")" + " with revoked permission "
                            + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
                } else if (!aInfo.exported) {
                    msg = "Permission Denial: starting " + intent.toString()
                            + " from " + callerApp + " (pid=" + callingPid
                            + ", uid=" + callingUid + ")"
                            + " not exported from uid " + aInfo.applicationInfo.uid;
                } else {
                    msg = "Permission Denial: starting " + intent.toString()
                            + " from " + callerApp + " (pid=" + callingPid
                            + ", uid=" + callingUid + ")"
                            + " requires " + aInfo.permission;
                }
                Slog.w(TAG, msg);
                throw new SecurityException(msg);
            }
    
            if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
                final String message = "Appop Denial: starting " + intent.toString()
                        + " from " + callerApp + " (pid=" + callingPid
                        + ", uid=" + callingUid + ")"
                        + " requires " + AppOpsManager.permissionToOp(
                                ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
                Slog.w(TAG, message);
                return false;
            } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
                final String message = "Appop Denial: starting " + intent.toString()
                        + " from " + callerApp + " (pid=" + callingPid
                        + ", uid=" + callingUid + ")"
                        + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
                Slog.w(TAG, message);
                return false;
            }
    
            return true;
        }
    

    1.mService.checkPermission(START_ANY_ACTIVITY, callingPid, callingUid);
    注册这个权限的应用可以启动任何的activity,如果有这个权限,那么其他的权限管理就形同虚设了。
    2.getComponentRestrictionForCallingPackage()
    检测权限组

    mService.checkComponentPermission(activityInfo.permission,
    callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
    3.getActionRestrictionForCallingPackage()
    检测权限
    mService.checkPermission(permission, callingPid, callingUid)

    回到上面new ActivityRecord
    ActivityRecord、TaskRecord、ActivityStack以及Activity启动模式详解

    继续往下走

    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                    int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                    ActivityRecord[] outActivity) {
            int result = START_CANCELED;
            try {
                mService.mWindowManager.deferSurfaceLayout();
                result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                        startFlags, doResume, options, inTask, outActivity);
            //省略代码
            return result;
        }
    
      private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
    
            //省略代码
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
            return START_SUCCESS;
        }
    
      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;
        }
    
      boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
            if (mStackSupervisor.inResumeTopActivity) {
                // Don't even start recursing.
                return false;
            }
    
            boolean result = false;
            try {
                // Protect against recursion.
                mStackSupervisor.inResumeTopActivity = true;
                result = resumeTopActivityInnerLocked(prev, options);
    
                // When resuming the top activity, it may be necessary to pause the top activity (for
                // example, returning to the lock screen. We suppress the normal pause logic in
                // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
                // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
                // to ensure any necessary pause logic occurs. In the case where the Activity will be
                // shown regardless of the lock screen, the call to
                // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
                final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
                if (next == null || !next.canTurnScreenOn()) {
                    checkReadyForSleep();
                }
            } finally {
                mStackSupervisor.inResumeTopActivity = false;
            }
    
            return result;
        }
    
      private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        //省略代码
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
        //省略代码
    }
    
      void startSpecificActivityLocked(ActivityRecord r,
                boolean andResume, boolean checkConfig) {
            // Is this activity's application already running?
            ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                    r.info.applicationInfo.uid, true);
    
            getLaunchTimeTracker().setLaunchTime(r);
    
            if (app != null && app.thread != null) {
                try {
                    if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                            || !"android".equals(r.info.packageName)) {
                        // Don't add this if it is a platform component that is marked
                        // to run in multiple processes, because this is actually
                        // part of the framework so doesn't make sense to track as a
                        // separate apk in the process.
                        app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                                mService.mProcessStats);
                    }
                    realStartActivityLocked(r, app, andResume, checkConfig);
                    return;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting activity "
                            + r.intent.getComponent().flattenToShortString(), e);
                }
    
                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
    
            mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                    "activity", r.intent.getComponent(), false, false, true);
        }
    

    app is running:realStartActivityLocked()
    app is not running:mService.startProcessLocked()

      final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
            //省略代码
    // Create activity launch transaction.
                    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                            r.appToken);
            //省略代码
                    // Schedule transaction.
                    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            //省略代码
            return true;
        }
    

    在Android8.0中,是通过ApplicationThread.scheduleLaunchActivity()对相关数据进行封装,然后通过调用ActivityThread类的sendMessage()发送出去。
    但是在Android9.0中,引入了ClientLifecycleManager和ClientTransactionHandler来辅助管理Activity生命周期。

      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();
            }
        }
    
    
        /** Target client. */
        private IApplicationThread mClient;
    
      public void schedule() throws RemoteException {
            mClient.scheduleTransaction(this);
        }
    

    mClient(private IApplicationThread mClient;)是一个IApplicationThread类型,这里其实是一个Binder,上面看到final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
    r.appToken);
    ActivityThread的内部类ApplicationThread派生这个接口类,因此这里实际调用了ActivityThread的scheduleTransaction()方法。

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

    这里调用了ActivityThread的父类ClientTransactionHandler的scheduleTransaction()

    public abstract class ClientTransactionHandler {
    
        // Schedule phase related logic and handlers.
    
        /** Prepare and schedule transaction for execution. */
        void scheduleTransaction(ClientTransaction transaction) {
            transaction.preExecute(this);
            sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
        }
    

    发送消息

    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;
    

    调用了mTransactionExecutor.execute(transaction)。也就是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");
        }
    
      /** Transition to the final state if requested by the transaction. */
        private void executeLifecycleState(ClientTransaction transaction) {
            final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
            if (lifecycleItem == null) {
                // No lifecycle request, return early.
                return;
            }
            log("Resolving lifecycle state: " + lifecycleItem);
    
            final IBinder token = transaction.getActivityToken();
            final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
    
            if (r == null) {
                // Ignore requests for non-existent client records for now.
                return;
            }
    
            // Cycle to the state right before the final requested state.
            cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
    
            // Execute the final transition with proper parameters.
            lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
            lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
        }
    
      private void cycleToPath(ActivityClientRecord r, int finish,
                boolean excludeLastState) {
            final int start = r.getLifecycleState();
            log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
            final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
            performLifecycleSequence(r, path);
        }
    
      private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
            final int size = path.size();
            for (int i = 0, state; i < size; i++) {
                state = path.get(i);
                log("Transitioning to state: " + state);
                switch (state) {
                    case ON_CREATE:
                        mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                                null /* customIntent */);
                        break;
                    case ON_START:
                        mTransactionHandler.handleStartActivity(r, mPendingActions);
                        break;
                    case ON_RESUME:
                        mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                                r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                        break;
                    case ON_PAUSE:
                        mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                                false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                                "LIFECYCLER_PAUSE_ACTIVITY");
                        break;
                    case ON_STOP:
                        mTransactionHandler.handleStopActivity(r.token, false /* show */,
                                0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                                "LIFECYCLER_STOP_ACTIVITY");
                        break;
                    case ON_DESTROY:
                        mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                                0 /* configChanges */, false /* getNonConfigInstance */,
                                "performLifecycleSequence. cycling to:" + path.get(size - 1));
                        break;
                    case ON_RESTART:
                        mTransactionHandler.performRestartActivity(r.token, false /* start */);
                        break;
                    default:
                        throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
                }
            }
        }
    

    在performLifecycleSequence()中首先执行的是case ON_CREATE对应的部分,它调用了ClientTransactionHandler的handleLaunchActivity()函数,
    mTransactionExecutor = new TransactionExecutor(this);传进去的this就是ActivityThread里实现的Handler。所以这个函数是由它的子类ActivityThread去实现的。

      public Activity handleLaunchActivity(ActivityClientRecord r,
                PendingTransactionActions pendingActions, Intent customIntent) {
            //省略代码
            WindowManagerGlobal.initialize();
    
            final Activity a = performLaunchActivity(r, customIntent);
            //省略代码
            return a;
        }
    
    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);
                //省略代码
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
                //省略代码
                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);
                    //省略代码
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }
                    //省略代码
            return activity;
        }
    

    这里调用了mInstrumentation.callActivityOnCreate(),可以看到activity.attach也是在这里调用的

    public void callActivityOnCreate(Activity activity, Bundle icicle,
                PersistableBundle persistentState) {
            prePerformCreate(activity);
            activity.performCreate(icicle, persistentState);
            postPerformCreate(activity);
        }
    
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
            mCanEnterPictureInPicture = true;
            restoreHasCurrentPermissionRequest(icicle);
            if (persistentState != null) {
                onCreate(icicle, persistentState);
            } else {
                onCreate(icicle);
            }
            writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
            mActivityTransitionState.readState(icicle);
    
            mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                    com.android.internal.R.styleable.Window_windowNoDisplay, false);
            mFragments.dispatchActivityCreated();
            mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
        }
    

    这里就调用了Activity的onCreate

    StartActivity流程.png

    接下来看下resume的流程

    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
                String reason) {
            // If we are getting ready to gc after going to the background, well
            // we are back active so skip it.
            unscheduleGcIdler();
            mSomeActivitiesChanged = true;
    
            // TODO Push resumeArgs into the activity for consideration
            final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
            if (r == null) {
                // We didn't actually resume the activity, so skipping any follow-up actions.
                return;
            }
    
            final Activity a = r.activity;
    
            if (localLOGV) {
                Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity
                        + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished);
            }
    
            final int forwardBit = isForward
                    ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
    
            // If the window hasn't yet been added to the window manager,
            // and this guy didn't finish itself or start another activity,
            // then go ahead and add the window.
            boolean willBeVisible = !a.mStartedActivity;
            if (!willBeVisible) {
                try {
                    willBeVisible = ActivityManager.getService().willActivityBeVisible(
                            a.getActivityToken());
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (r.mPreserveWindow) {
                    a.mWindowAdded = true;
                    r.mPreserveWindow = false;
                    // Normally the ViewRoot sets up callbacks with the Activity
                    // in addView->ViewRootImpl#setView. If we are instead reusing
                    // the decor view we have to notify the view root that the
                    // callbacks may have changed.
                    ViewRootImpl impl = decor.getViewRootImpl();
                    if (impl != null) {
                        impl.notifyChildRebuilt();
                    }
                }
                if (a.mVisibleFromClient) {
                    if (!a.mWindowAdded) {
                        a.mWindowAdded = true;
                        wm.addView(decor, l);
                    } else {
                        // The activity will get a callback for this {@link LayoutParams} change
                        // earlier. However, at that time the decor will not be set (this is set
                        // in this method), so no action will be taken. This call ensures the
                        // callback occurs with the decor set.
                        a.onWindowAttributesChanged(l);
                    }
                }
    
                // If the window has already been added, but during resume
                // we started another activity, then don't yet make the
                // window visible.
            } else if (!willBeVisible) {
                if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
                r.hideForNow = true;
            }
    
            // Get rid of anything left hanging around.
            cleanUpPendingRemoveWindows(r, false /* force */);
    
            // The window is now visible if it has been added, we are not
            // simply finishing, and we are not starting another activity.
            if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
                if (r.newConfig != null) {
                    performConfigurationChangedForActivity(r, r.newConfig);
                    if (DEBUG_CONFIGURATION) {
                        Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
                                + r.activity.mCurrentConfig);
                    }
                    r.newConfig = null;
                }
                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
                WindowManager.LayoutParams l = r.window.getAttributes();
                if ((l.softInputMode
                        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                        != forwardBit) {
                    l.softInputMode = (l.softInputMode
                            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                            | forwardBit;
                    if (r.activity.mVisibleFromClient) {
                        ViewManager wm = a.getWindowManager();
                        View decor = r.window.getDecorView();
                        wm.updateViewLayout(decor, l);
                    }
                }
    
                r.activity.mVisibleFromServer = true;
                mNumVisibleActivities++;
                if (r.activity.mVisibleFromClient) {
                    r.activity.makeVisible();
                }
            }
    
            r.nextIdle = mNewActivities;
            mNewActivities = r;
            if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
            Looper.myQueue().addIdleHandler(new Idler());
        }
    

    performResumeActivity不做解释了,调用流程和onCreate差不多,我们可以看到wm.addView(decor, l)这句代码。ViewManager wm = a.getWindowManager();
    这个a是Activity,在Activity中,getWindowManager返回的对象是这样初始化的
    mWindowManager = mWindow.getWindowManager();
    mWindow是mWindow = new PhoneWindow(this, window, activityConfigCallback);,getWindowManager返回的还是Window类中的mWindowManager,看看怎么初始化的mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    所以最终ViewManager wm = a.getWindowManager();获取到的对象就是WindowManagerImpl。看看WindowManagerImpl中的addView

        @Override
        public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
            applyDefaultToken(params);
            mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
        }
    

    调用到WindowManagerGlobal中

      public void addView(View view, ViewGroup.LayoutParams params,
                Display display, Window parentWindow) {
                 //省略代码
                // do this last because it fires off messages to start doing things
                try {
                    root.setView(view, wparams, panelParentView);
                } catch (RuntimeException e) {
                    // BadTokenException or InvalidDisplayException, clean up.
                    if (index >= 0) {
                        removeViewLocked(index, true);
                    }
                    throw e;
                }
            }
        }
    

    看下root.setView

      public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
            synchronized (this) {
                if (mView == null) {
                    mView = view;
                    //省略代码
                    // Schedule the first layout -before- adding to the window
                    // manager, to make sure we do the relayout before receiving
                    // any other events from the system.
                    requestLayout();
                    //省略代码
                }
            }
        }
    
        @Override
        public void requestLayout() {
            if (!mHandlingLayoutInLayoutRequest) {
                checkThread();
                mLayoutRequested = true;
                scheduleTraversals();
            }
        }
    
        void scheduleTraversals() {
            if (!mTraversalScheduled) {
                mTraversalScheduled = true;
                mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
                mChoreographer.postCallback(
                        Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
                if (!mUnbufferedInputDispatch) {
                    scheduleConsumeBatchedInput();
                }
                notifyRendererOfFramePending();
                pokeDrawLockIfNeeded();
            }
        }
    

    这一句mChoreographer.postCallback(
    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);会调用mTraversalRunnable方法

        final class TraversalRunnable implements Runnable {
            @Override
            public void run() {
                doTraversal();
            }
        }
    
        void doTraversal() {
            if (mTraversalScheduled) {
                mTraversalScheduled = false;
                mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
    
                if (mProfile) {
                    Debug.startMethodTracing("ViewAncestor");
                }
    
                performTraversals();
    
                if (mProfile) {
                    Debug.stopMethodTracing();
                    mProfile = false;
                }
            }
        }
    

    performTraversals这里面就是刷图流程了


    刷图流程.png

    可以看到,先调用的onResume,再刷图

    相关文章

      网友评论

          本文标题:UI绘制(一)——从startActivity到生命周期调用

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