美文网首页
6.0应用内Activity启动流程

6.0应用内Activity启动流程

作者: Noblel | 来源:发表于2018-01-04 20:42 被阅读0次

startActivity(new Intent(this, TestActivity.class)

public void startActivity(Intent intent) {
    //执行方法2
    this.startActivity(intent, null);
}

/**
 * 方法2
 */
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        //如果bundle不为null就执行方法4
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        //可以看到我们上面传过来的是null,所以会执行方法3,最终也会执行到方法4里面
        startActivityForResult(intent, -1);
    }
}

/**
 * 方法3
 */
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}

/**
 * 方法4
 */
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    //是否嵌套在其他Activity上
    if (mParent == null) {
        //这里是默认没有的父Activity的(不是Manifest中的parentActivityName),以前我一直以为是的TNT
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            //主要看这个方法,执行了方法5
            //mMainThread.getApplicationThread()返回的是一个ApplicationThread类,他是ActivityThread内部类
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        ......
    } 
    ....
}

Instrumentation:用来监视整个应用或者所有待测活动与Android系统交互的所有过程
Instrumentation.ActivityMonitor: 用来监视应用中的单个活动,可以监视一些指定的视图。创建好ActivityMonitor的实例后,通过调用Instrumentation.addMonitor函数来添加这个实例。当活动启动后,系统会匹配Instrumentation中的ActivityMonitory实例列表,如果匹配,就会累加计数器。

/**
 * 方法5
 */
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    //Binder通信
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    ....
    try {
        ....
        //先获取服务,执行ActivityManagerService的startActivity()方法,为什么是ActivityManagerService以后再分析。执行方法6
        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);
    }
    ....
}

ActivityManagerService:Activity的管理服务

/**
 * 方法6
 */
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle options) {
    //又调用了方法7
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
        resultWho, requestCode, startFlags, profilerInfo, options,
        UserHandle.getCallingUserId());
}

/**
 * 方法7
 */
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
    enforceNotIsolatedCaller("startActivity");
    userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
            false, ALLOW_FULL_ONLY, "startActivity", null);
    // TODO: Switch to user app stacks here.
    //执行方法8
    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, options, false, userId, null, null);
}

ActivityStackSupervisor:Activity的栈管理器,管理着两个重要的Activity栈,
mHomeStack 管理着Launcher,RecentTask,Keyguad
mFocusedStack 管理其他的

/**
 * 方法8
 */
final 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 config,
        Bundle options, boolean ignoreTargetSecurity, int userId,
        IActivityContainer iContainer, TaskRecord inTask) {
        

        .....
        //直接定位到1045行,又调用了方法9
        int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                voiceSession, voiceInteractor, resultTo, resultWho,
                requestCode, callingPid, callingUid, callingPackage,
                realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                componentSpecified, null, container, inTask);



/**
 * 方法9
 */
 final int startActivityLocked(IApplicationThread caller,
        Intent intent, String resolvedType, ActivityInfo aInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode,
        int callingPid, int callingUid, String callingPackage,
        int realCallingPid, int realCallingUid, int startFlags, Bundle options,
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        ActivityContainer container, TaskRecord inTask) {
    int err = ActivityManager.START_SUCCESS;
    ...
    //执行方法10
    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, true, options, inTask);
    ...
    return err;
}

/**
 * 方法10
 */
 final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
        boolean doResume, Bundle options, TaskRecord inTask) {
    ....
    //由于我们没有配置launchMode,所以上面的if判断不会执行
    if (r.packageName != null) {
        ActivityStack topStack = mFocusedStack;
        ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
        //判断当前要启动得Activity是否是栈顶Activity,如果是某些情况下就不用重新启动了
        if (top != null && r.resultTo == null) {
            ...
        }
        
        if (r.resultTo == null && inTask == null && !addingToTask
            && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            ....
        } else if (sourceRecord != null) {
            //sourceRecord这里是MainActivity,于是MainActivity的task赋给新的Activity了
            final TaskRecord sourceTask = sourceRecord.task;
            ......
            targetStack = sourceTask.stack;
        ....
        // An existing activity is starting this new activity, so we want
        // to keep the new one in the same task as the one that is starting
        // it.
        } else {  
            ......  
        }  
    }
    .....
    targetStack.mLastPausedActivity = null;
    //最终会执行到方法11
    targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
    return ActivityManager.START_SUCCESS;
}

ActivityStack:

/**
 * 方法11
 */
 final void startActivityLocked(ActivityRecord r, boolean newTask,
        boolean doResume, boolean keepCurTransition, Bundle options) {
    //这里newTask为false,
    TaskRecord rTask = r.task;
    final int taskId = rTask.taskId; 
    ....
    TaskRecord task = null;
    if (!newTask) {
        // If starting in an existing task, find where that is...
        .....
    }
    
    
    task = r.task;

    // Slot the activity into the history stack and proceed
    task.addActivityToTop(r);
    task.setFrontOfTask();
    
    r.putInHistory();
    //是否执行Resume
    if (doResume) {
        //执行方法12
        mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
    }
}

ActivityStackSupervisor:

/**
 * 方法12
 */
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
        Bundle targetOptions) {
    if (targetStack == null) {
        targetStack = mFocusedStack;
    }
    // Do targetStack first.
    boolean result = false;
    if (isFrontStack(targetStack)) {
        //执行方法13
        result = targetStack.resumeTopActivityLocked(target, targetOptions);
    }
    
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (stack == targetStack) {
                // Already started above.
                continue;
            }
            if (isFrontStack(stack)) {
                //执行目标Activity的启动流程
                stack.resumeTopActivityLocked(null);
            }
        }
    }
    return result;
}


/**
 * 方法13,MainActivity就进入Paused状态后还会调用此方法
 */
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        .....
        //执行方法14
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    return result;
}


/**
 * 方法14
 */
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

    final ActivityRecord next = topRunningActivityLocked(null);
    
    // If the top activity is the resumed one, nothing to do.
    if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                mStackSupervisor.allResumedActivitiesComplete()) {
        .......
    }
    
    // If we are sleeping, and there is no resumed activity, and the top
    // activity is paused, well that is the state we want.
    if (mService.isSleepingOrShuttingDown()
            && mLastPausedActivity == next
            && mStackSupervisor.allPausedActivitiesComplete()) {
            .....
    }
    
    if (mResumedActivity != null) {
            //中断正在显示的Activity,执行方法15
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
    }
    if (pausing) {
            ...
            if (next.app != null && next.app.thread != null) {
                mService.updateLruProcessLocked(next.app, true, null);
            }
            return true;
    }
    ...
    if (next.app != null && next.app.thread != null) {
         ...
         try {
            .....
         } catch() {
            ....
         }
         mStackSupervisor.startSpecificActivityLocked(next, true, false);
         return 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);

    r.task.stack.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.versionCode,
                        mService.mProcessStats);
            }
            //真正启动Activity最后执行app.thread.scheduleLaunchActivity(...);
            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);
}

/**
 * 方法15
 */
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming, boolean dontWait) {
    ....
    ActivityRecord prev = mResumedActivity;
    ....
    mResumedActivity = null;
    mPausingActivity = prev;
    mLastPausedActivity = prev;
    mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
    将上个Activity状态置为PAUSING
    prev.state = ActivityState.PAUSING;
    if (prev.app != null && prev.app.thread != null) {
            ...
            try {
                ....
                //执行方法IApplicationThread的schedulePauseActivity方法
                //ApplicationThread是IApplicationThread实例而且是ActivityThread的内部类
                //这里就不再查找了,直接看方法了,执行方法16
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            } 
        ....
    } else {
        ....
    }
    // If we are not going to sleep, we want to ensure the device is
    // awake until the next activity is started.
    if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {
        mStackSupervisor.acquireLaunchWakelock();
    }
    
    if (mPausingActivity != null) {
        // Have the window manager pause its key dispatching until the new
        // activity has started.  If we're pausing the activity just because
        // the screen is being turned off and the UI is sleeping, don't interrupt
        // key dispatch; the same activity will pick it up again on wakeup.
        if (!uiSleeping) {
            //暂停事件分发
            prev.pauseKeyDispatchingLocked();
        } 
        ....

        if (dontWait) {
            // If the caller said they don't want to wait for the pause, then complete
            // the pause now.
            //调用方法
            completePauseLocked(false);
            return false;

        } else {
            // Schedule a pause timeout in case the app doesn't respond.
            // We don't give it much time because this directly impacts the
            // responsiveness seen by the user.
            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
            msg.obj = prev;
            prev.pauseTime = SystemClock.uptimeMillis();
            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
            return true;
        }
    } 
    
}

/**
 * 方法16
 */    
public final void schedulePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport) {
        //这里就是H就是一个Handler  ----> private class H extends Handler 
        //直接调用方法18
        sendMessage(
                finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                token,
                (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                configChanges);
}

/**
 * 方法18
 */    
private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        //这里会调用我们的onUserInteraction()和onUserLeaveHint();
        if (userLeaving) {
            performUserLeavingActivity(r);
        }
        r.activity.mConfigChangeFlags |= configChanges;
        
        //执行方法19
        performPauseActivity(token, finished, r.isPreHoneycomb());

        // Make sure any pending writes are now committed.
        if (r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }

        // Tell the activity manager we have paused.
        if (!dontReport) {
            try {
                //通知服务端Activity暂停了,调用服务端方法
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
            }
        }
        mSomeActivitiesChanged = true;
    }
}

@Override
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            //交给stack
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}

/**
 * 去掉了log
 */ 
final void activityPausedLocked(IBinder token, boolean timeout) {
    final ActivityRecord r = isInStackLocked(token);
    if (r != null) {
        //移除暂停超时消息
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        if (mPausingActivity == r) {
            //执行方法
            completePauseLocked(true);
        } else {
            if (r.finishing && r.state == ActivityState.PAUSING) {
                finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
            }
        }
    }
}

private void completePauseLocked(boolean resumeNext) {
    ActivityRecord prev = mPausingActivity;

    if (prev != null) {
        prev.state = ActivityState.PAUSED;
        if (prev.finishing) {
            //如果已经finish就执行此方法
            prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
        } else if (prev.app != null) {
            if (mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
                    ....
            }
            .....
            else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {
                // If we were visible then resumeTopActivities will release resources before
                // stopping.
                mStackSupervisor.mStoppingActivities.add(prev);
                if (mStackSupervisor.mStoppingActivities.size() > 3 ||
                        prev.frontOfTask && mTaskHistory.size() <= 1) {
                    mStackSupervisor.scheduleIdleLocked();
                } else {
                    mStackSupervisor.checkReadyForSleepLocked();
                }
            }
        } else {
            prev = null;
        }
        ....
    }

    if (resumeNext) {
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        if (!mService.isSleepingOrShuttingDown()) {
            mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
        } else {
            mStackSupervisor.checkReadyForSleepLocked();
            ActivityRecord top = topStack.topRunningActivityLocked(null);
            if (top == null || (prev != null && top != prev)) {
                // If there are no more activities available to run,
                // do resume anyway to start something.  Also if the top
                // activity on the stack is not the just paused activity,
                // we need to go ahead and resume it to ensure we complete
                // an in-flight app switch.
                //看上面注释,执行方法12,后面两个参数为null
                mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
            }
        }
    }

    if (prev != null) {
        prev.resumeKeyDispatchingLocked();
        .....
    }

    // Notfiy when the task stack has changed
    mService.notifyTaskStackChangedLocked();
}

/**
 * 方法19
 */    
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
        boolean saveState) {
    ....
    try {
        // Next have the activity save its current state and managed dialogs...
        if (!r.activity.mFinished && saveState) {
            //这里就会调用到我们OnSaveInstanceState
            callCallActivityOnSaveInstanceState(r);
        }
        // Now we are idle.
        r.activity.mCalled = false;
        //调用方法20
        mInstrumentation.callActivityOnPause(r.activity);
        .....
    } 
    .....
    r.paused = true;

    // Notify any outstanding on paused listeners
    ArrayList<OnActivityPausedListener> listeners;
    synchronized (mOnPauseListeners) {
        listeners = mOnPauseListeners.remove(r.activity);
    }
    int size = (listeners != null ? listeners.size() : 0);
    for (int i = 0; i < size; i++) {
        listeners.get(i).onPaused(r.activity);
    }

    return !r.activity.mFinished && saveState ? r.state : null;
}

Instrumentation

/**
 * 方法20
 */    
public void callActivityOnPause(Activity activity) {
    activity.performPause();
}

Activity:

/**
 * 方法21
 */    
final void performPause() {
    mDoReportFullyDrawn = false;
    mFragments.dispatchPause();
    mCalled = false;
    //这里就是调用我们Activity的onPause方法了,有点小惊喜
    onPause();
    mResumed = false;
    if (!mCalled && getApplicationInfo().targetSdkVersion
            >= android.os.Build.VERSION_CODES.GINGERBREAD) {
        throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onPause()");
    }
    mResumed = false;
}

/**
 * 方法22,也就是我们平时所覆盖的onPause方法
 */
protected void onPause() {
    getApplication().dispatchActivityPaused(this);
    mCalled = true;
}

总结下: 我确定了一个细节 显示前一个onPause执行才会执行第二个界面的onCreate。

Activity启动流程图.jpg

相关文章

网友评论

      本文标题:6.0应用内Activity启动流程

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