AMS源码分析--finish()源码分析

698 阅读6分钟

前言

源码分析基于android-26

案例

  1. 在MainActivity中通过startActivityForResult()方法启动AActivity
Intent intent = new Intent(MainActivity.this, AActivity.class);
startActivityForResult(intent,1);
  1. AActivity中点击返回键日志如下
04-06 15:57:22.291 E/geziqiang: onPause AActivity
04-06 15:57:22.296 E/geziqiang: onActivityResult MainActivity
04-06 15:57:22.296 E/geziqiang: onRestart MainActivity
04-06 15:57:22.298 E/geziqiang: onResume MainActivity
04-06 15:57:22.694 E/geziqiang: onStop AActivity
04-06 15:57:22.694 E/geziqiang: onDestroy AActivity
  1. MainActivity在界面展示之后才会执行AActivity的onStop方法

下面从源码中分析为啥是这个顺序

1. finish()方法


/**
 * Call this when your activity is done and should be closed.  The
 * ActivityResult is propagated back to whoever launched you via
 * onActivityResult().
 */
public void finish() {
    finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
/**
 * Finishes the current activity and specifies whether to remove the task associated with this
 * activity.
 */
private void finish(int finishTask) {
    if (mParent == null) {
        int resultCode;
        Intent resultData;
        synchronized (this) {
            // 获取返回的结果码和数据,通过setResult()方法进行设置
            // 此处resultCode为RESULT_CANCELED,resultData为null
            resultCode = mResultCode;
            resultData = mResultData;
        }
        try {
            // 重点是这个方法
            if (ActivityManager.getService()
                    .finishActivity(mToken, resultCode, resultData, finishTask)) {
                mFinished = true;
            }
        } catch (RemoteException e) {
            // Empty
        }
    } else {
        // finishFromChild最终也会进入当前方法
        mParent.finishFromChild(this);
    }
}

2. ActivityManager.getService()是啥?

/**
 * @hide
 */
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("activity");
            final IActivityManager am = IActivityManager.Stub.asInterface(b);
            return am;
        }
    };

可见,先是从ServiceManager中获取名为"activity"对应的IBinder对象(在ActivityManagerService#setSystemProcess方法中进行了注册),然后通过IActivityManager.Stub.asInterface转换为ActivityManagerService的代理。最后通过Binder机制交由ActivityManagerServic处理

3. 继续看ActivityManagerService#finishActivity

@Override
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
        int finishTask) {
    synchronized(this) {
        // 获取AActivity对应的ActivityRecord对象
        ActivityRecord r = ActivityRecord.isInStackLocked(token);
        if (r == null) {
            return true;
        }
        // Keep track of the root activity of the task before we finish it
        // 获取AActivity对应的TaskRecord对象,TaskRecord包含当前的所有activity和回退栈
        TaskRecord tr = r.getTask();
        // 获取栈底的activity,此时是MainActivity
        ActivityRecord rootR = tr.getRootActivity();
        try {
            boolean res;
            // 传入的finishTask是DONT_FINISH_TASK_WITH_ACTIVITY,走else分支
            final boolean finishWithRootActivity =
                    finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
            if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
                    || (finishWithRootActivity && r == rootR)) {
                // 省略。。。
            } else {
                // 重点是这里
                res = tr.getStack().requestFinishActivityLocked(token, resultCode,
                        resultData, "app-request", true);
            }
            return res;
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }
}

4. ActivityStack#requestFinishActivityLocked最终会调用到ActivityStack#finishActivityLocked方法

/**
 * @return Returns true if this activity has been removed from the history
 * list, or false if it is still in the list and will be removed later.
 */
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
        String reason, boolean oomAdj, boolean pauseImmediately) {
    // 是否正在finishing,是的话直接返回
    if (r.finishing) {
        Slog.w(TAG, "Duplicate finish request for " + r);
        return false;
    }
    
    mWindowManager.deferSurfaceLayout();
    try {
        // 该r的finishing设置为true,此时r就是AActiivty对应的ActivityRecord
        r.makeFinishingLocked();
        final TaskRecord task = r.getTask();
        final ArrayList<ActivityRecord> activities = task.mActivities;
        final int index = activities.indexOf(r);

        r.pauseKeyDispatchingLocked();
        
        // 如果当前activity所在的task没有获取焦点,设置获取焦点
        adjustFocusedActivityStackLocked(r, "finishActivity");
        
        // 将resultCode和resultData组装成ActivityResult对象,并添加到MainActivity对应的ActivityRecord的results集合中
        finishActivityResultsLocked(r, resultCode, resultData);
        // 判断AActivity是否是栈底activity
        final boolean endTask = index <= 0;
        final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
        // mResumedActivity保留这当前栈可见的activity,此时就是AActivity,走if分支
        if (mResumedActivity == r) {
            // WMS切换
            mWindowManager.prepareAppTransition(transit, false);
            // Tell window manager to prepare for this one to be removed.
            r.setVisibility(false);
            // mPausingActivity为null,下面也有分析
            if (mPausingActivity == null) {
                // 重点看这个方法
                startPausingLocked(false, false, null, pauseImmediately);
            }
            if (endTask) {
                mStackSupervisor.removeLockedTaskLocked(task);
            }
        } else if (r.state != ActivityState.PAUSING) {
            // 如果状态不是PAUSING 执行该流程,以后启动流程进行分析
            // 代码省略
        }else {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
        }
        return false;
    } finally {
        mWindowManager.continueSurfaceLayout();
    }
}

为啥说mPausingActivity == null成立呢?MainActivity不是进入过Pause状态吗? 答案和启动流程有关,startActivity()的确会设置当前一个Activty为mPausingActivity,但是通过handle延迟500ms之后再将mPausingActivity设置为null,然后进入scheduleLaunch之类后的流程。 (没看懂也没关系,打算在介绍startActivities源码时进行分析)

5. ActivityStack#startPausingLocked

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean pauseImmediately) {
        // 省略部分代码...
        // prev指向resume状态的activity,此时就是AActivity
        ActivityRecord prev = mResumedActivity;
        // 不成立
        if (prev == null) {
            if (resuming == null) {
                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }
        // 省略部分代码...
        
        mResumedActivity = null;
        // 此处给mPausingActivity赋值
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        prev.state = ActivityState.PAUSING;
        prev.getTask().touchActiveTime();
        clearLaunchTime(prev);
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
        // AActivity已经启动过,走if分支
        if (prev.app != null && prev.app.thread != null) {
            try {
                mService.updateUsageStats(prev, false);
                // 最终通过handle调用activity的onPause方法
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, pauseImmediately);
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }

        // If we are not going to sleep, we want to ensure the device is
        // awake until the next activity is started.
        if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
            mStackSupervisor.acquireLaunchWakelock();
        }

        if (mPausingActivity != null) {
            // 省略。。。
            // 传入的pauseImmediately为false,走else分支
            if (pauseImmediately) {
                // If the caller said they don't want to wait for the pause, then complete
                // the pause now.
                completePauseLocked(false, resuming);
                return false;
            } else {
                //  重点看这个方法
                schedulePauseTimeout(prev);
                return true;
            }

        } else {
            // 省略。。。
        }
    }

6. ActivityStack#schedulePauseTimeout

private void schedulePauseTimeout(ActivityRecord r) {
    final Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
    msg.obj = r;
    r.pauseTime = SystemClock.uptimeMillis();
    mHandler.sendMessageDelayed(msg, 500);
    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
}

通过Handler延迟500ms发送一个PAUSE_TIMEOUT_MSG消息

7. 在看下app.thread.schedulePauseActivity做了什么

private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport, int seq) {
    ActivityClientRecord r = mActivities.get(token);
    if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
    if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
        return;
    }
    if (r != null) {
        //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
        if (userLeaving) {
            performUserLeavingActivity(r);
        }

        r.activity.mConfigChangeFlags |= configChanges;
        performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");

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

        // Tell the activity manager we have paused.
        if (!dontReport) {
            try {
                // 重点是这个方法
                ActivityManager.getService().activityPaused(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
        mSomeActivitiesChanged = true;

8. ActivityManagerService#activityPaused源码

@Override
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            // 重点是这个方法
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}

9. ActivityStack#activityPausedLocked

final void activityPausedLocked(IBinder token, boolean timeout) {
    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
        "Activity paused: token=" + token + ", timeout=" + timeout);

    final ActivityRecord r = isInStackLocked(token);
    if (r != null) {
        // 移除延迟500ms的PAUSE_TIMEOUT_MSG消息
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        if (mPausingActivity == r) {
            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                    + (timeout ? " (due to timeout)" : " (pause complete)"));
            mService.mWindowManager.deferSurfaceLayout();
            try {
                completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
            } finally {
                mService.mWindowManager.continueSurfaceLayout();
            }
            return;
        } else {
            EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                    r.userId, System.identityHashCode(r), r.shortComponentName,
                    mPausingActivity != null
                        ? mPausingActivity.shortComponentName : "(none)");
            if (r.state == ActivityState.PAUSING) {
                r.state = ActivityState.PAUSED;
                if (r.finishing) {
                    if (DEBUG_PAUSE) Slog.v(TAG,
                            "Executing finish of failed to pause activity: " + r);
                    finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
                }
            }
        }
    }
    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}

10. ActivityStack#completePauseLocked

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
        ActivityRecord prev = mPausingActivity;
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);

        if (prev != null) {
            final boolean wasStopping = prev.state == STOPPING;
            prev.state = ActivityState.PAUSED;
            // prev就是AActivity,之前已经设置了finishing为true
            if (prev.finishing) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
                // 只是添加到stop列表中
                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
            } else if (prev.app != null) {
                。。。
            } else {
                。。。
            }
            。。。
            // 重新设置为null
            mPausingActivity = null;
        }
        // resumeNext是true 进入
        if (resumeNext) {
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDownLocked()) {
                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
            } else {
                mStackSupervisor.checkReadyForSleepLocked
                // 获取栈顶第一个非finishing状态的activity,此时是MainActivity
                ActivityRecord top = topStack.topRunningActivityLocked();
                // 条件满足进入
                if (top == null || (prev != null && top != prev)) {
                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
                }
            }
        }
        省略。。。
    }

11. ActivityStack#finishCurrentActivityLocked

final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
        // 找到栈顶非finishing状态的Activity,此时是MainActivity
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
        // 条件满足
        if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
                && next != null && !next.nowVisible) {
            if (!mStackSupervisor.mStoppingActivities.contains(r)) {
                // 添加到stop列表中
                addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */);
            }
            r.state = STOPPING;
            if (oomAdj) {
                mService.updateOomAdjLocked();
            }
            return r;
        }
        省略。。。
}

12. 继续看ActivityStackSupervisor#resumeFocusedStackTopActivityLock, 该方法最终调用到ActivityStack#resumeTopActivityInnerLocked方法

13. ActivityStack#resumeTopActivityInnerLocked

  private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // 省略部分代码
    // 找到MainActivity
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    // MainActivity已经启动过,进入if分支
      if (next.app != null && next.app.thread != null) {
          try {
            // Deliver all pending results.
            ArrayList<ResultInfo> a = next.results;
            if (a != null) {
                final int N = a.size();
                if (!next.finishing && N > 0) {
                    if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                            "Delivering results to " + next + ": " + a);
                   // 最终进入onActivityResult next.app.thread.scheduleSendResult(next.appToken, a);
                }
            }

            if (next.newIntents != null) {
                next.app.thread.scheduleNewIntent(
                        next.newIntents, next.appToken, false /* andPause */);
            }
    
                // Well the app will no longer be stopped.
                // Clear app token stopped state in window manager if needed.
                next.notifyAppResumed(next.stopped);
    
                next.sleeping = false;
                mService.showUnsupportedZoomDialogIfNeededLocked(next);
                mService.showAskCompatModeDialogLocked(next);
                next.app.pendingUiClean = true;
                next.app.forceProcessStateUpTo(mService.mTopProcessState);
                next.clearOptionsLocked();
                // 最后进入OnResume方法
                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                        mService.isNextTransitionForward(), resumeAnimOptions);
                // 省略部分代码
            } catch (Exception e) {
                ...
            }
          }
  }

到这里位置,我们知道顺序是AAtivity#onPause--->MainAtivity#onActivityResult--->MainAtivity#onRestart--->MainAtivity#onResume,那么AAtivity的onStop和onDestroy是什么调用的呢? 答案是在ActivityThread的handleResumeActivity方法中,有一行代码是Looper.myQueue().addIdleHandler(new Idler()); new Idler()会在在Handle空闲时候执行

  private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
            ActivityClientRecord a = mNewActivities;
            if (a != null) {
                mNewActivities = null;
                IActivityManager am = ActivityManager.getService();
                ActivityClientRecord prev;
                do {
                    if (a.activity != null && !a.activity.mFinished) {
                        try {
                            //重点是这个方法
                            am.activityIdle(a.token, a.createdConfig, stopProfiling);
                            a.createdConfig = null;
                        } catch (RemoteException ex) {
                            throw ex.rethrowFromSystemServer();
                        }
                    }
                    prev = a;
                    a = a.nextIdle;
                    prev.nextIdle = null;
                } while (a != null);
            }
            if (stopProfiling) {
                mProfiler.stopProfiling();
            }
            ensureJitEnabled();
            return false;
        }
    }

14. ActivityStackSupervisor#activityIdleInternalLocked方法中

for (int i = 0; i < NS; i++) {
    r = stops.get(i);
    final ActivityStack stack = r.getStack();
    if (stack != null) {
        if (r.finishing) {
            stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
        } else {
            stack.stopActivityLocked(r);
        }
    }
}

// Finish any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = 0; i < NF; i++) {
    r = finishes.get(i);
    final ActivityStack stack = r.getStack();
    if (stack != null) {
        activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
    }
}

15. 最后通过ActivityThread进行事件分发

1.r.app.thread.scheduleDestroyActivity
2.r.app.thread.handleDestroyActivity
3.r.activity.performStop(r.mPreserveWindow);
4.mInstrumentation.callActivityOnDestroy(r.activity);
5.activity.performDestroy();

总结

finish() 流程和启动流程都很复杂,一次次的觉得这下真弄懂的时候,却被下一次打脸