Activity的Finish过程分析

822 阅读4分钟

废话不多说了,直接上代码。==。

// Activity.java
public void finish() {
    if (mParent == null) {
        int resultCode;
        Intent resultData;
        synchronized (this) {
            resultCode = mResultCode;
            resultData = mResultData;
        }
        ……
         //调用到AMS中的finishActivity
        if (ActivityManagerNative.getDefault()
            .finishActivity(mToken, resultCode, resultData)) {
            mFinished = true;
        }
        ……
    } else {
        mParent.finishFromChild(this);
    }
}

Activity的finish过程会通过Binder调用到AMS的finishActivity。

@Override
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
    ……
    synchronized(this) {
        ActivityRecord r = ActivityRecord.isInStackLocked(token);
        ……
        final long origId = Binder.clearCallingIdentity();
        boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
                resultData, "app-request", true);//终止当前activity
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}

final boolean requestFinishActivityLocked(IBinder token, int resultCode,
        Intent resultData, String reason, boolean oomAdj) {
    ActivityRecord r = isInStackLocked(token);
    ...
    //终止当前activity
    finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
    return true;
}

finishActivity调用到ActivityRecord对应的ActivityStack中的requestFinishActivityLocked。紧接着再调用finishActivityLocked。

//frameworks/base/services/java/com/android/server/am/ActivityStack.java
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
        String reason, boolean oomAdj) {
    ...
    if (mResumedActivity == r) {
        ……
        // Tell window manager to prepare for this one to be removed.
        mWindowManager.setAppVisibility(r.appToken, false);

        if (mPausingActivity == null) {
        
            startPausingLocked(false, false);//开始pause流程,这是finish周期的第一步
        }
    }
    ……
    return false;
}

finishActivityLocked通过startPauseingLocked方法来暂停当前的activity。

final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
    
    ActivityRecord prev = mResumedActivity;//将要被暂停的activity
    
    mResumedActivity = null; //pause流程会将mResumeActivity置null
    mPausingActivity = prev;//正在被暂停的activity
    mLastPausedActivity = prev;//上一个被暂停的activity
    mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
            || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
    prev.state = ActivityState.PAUSING;//切换状态为PAUSING
    prev.task.touchActiveTime();
    clearLaunchTime(prev);
    final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();//代表即将要启动的activity
    if (next == null || next.task != prev.task) {
        prev.updateThumbnail(screenshotActivities(prev), null);
    }
    stopFullyDrawnTraceIfNeeded();

    mService.updateCpuStats();

    if (prev.app != null && prev.app.thread != null) {//Launcher启动 走这里 
        ...
        prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                    userLeaving, prev.configChangeFlags);//取出ApplicationThread对象通知其进入Paused状态
        ...
    } else {
        mPausingActivity = null;
        mLastPausedActivity = null;
        mLastNoHistoryActivity = null;
    }
    ...
}

startPausingLocked方法负责暂停当前activity,它通过IApplicationThread这个Binder代理调用schedulePauseActivity通知应用端暂停当前activity。

private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges) {
    ActivityClientRecord r = mActivities.get(token);
    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());//调用performPauseActivity函数来调用Activity.onPause回调

        // Make sure any pending writes are now committed.
        if (r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }
        //通知ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以完成未竟的事情
        // Tell the activity manager we have paused.
        try {
            ActivityManagerNative.getDefault().activityPaused(token);
        } catch (RemoteException ex) {
        }
    }
}

schedulePauseActivity调用handlePauseActivity方法来执行暂停过程,这里会回调Activity生命周期的onPause方法,完成暂停后通过activityPaused方法通知AMS。

//activity被暂停后 通知AMS已经执行完毕
@Override
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);//获取当前的activityStack
        if (stack != null) {
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}

//ActivityStack.java 通知activity被paused
final void activityPausedLocked(IBinder token, boolean timeout) {
    
    //这里的token是被暂停的activity的token    
    final ActivityRecord r = isInStackLocked(token);//得到暂停的activity Launcher启动即为Launcher对应的Activity
    if (r != null) {
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        if (mPausingActivity == r) {//true 这个在startPausingLocked中被设置的 
            r.state = ActivityState.PAUSED;//改变状态为PAUSING->PAUSEd
            completePauseLocked();//完成暂停acitivty的操作
        }
        ...
    }
}

AMS的activityPaused通过ActivityStack的activityPausedLocked方法来完成进一步完成暂停Activity的工作。随后进一步调用completePauseLocked。

//完成暂停动作后的逻辑
private void completePauseLocked() {
    ActivityRecord prev = mPausingActivity;
    if (prev != null) {
        if (prev.finishing) {//主动finish时候是走这个分支,如果finishing标记为true表示这个activity是要finish
            prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
        }
        ...
        mPausingActivity = null;//完成了pause过程 这里需要将mPausingActivity置为null
    }

    final ActivityStack topStack = mStackSupervisor.getFocusedStack();
    if (!mService.isSleepingOrShuttingDown()) {//未休眠
        mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
    } 
    ...
}
//finish当前activity
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
    ……
    // make sure the record is cleaned out of other places.
    mStackSupervisor.mStoppingActivities.remove(r);//从mStackSupervisor中移除activity的信息
    mStackSupervisor.mGoingToSleepActivities.remove(r);
    mStackSupervisor.mWaitingVisibleActivities.remove(r);
    if (mResumedActivity == r) {
        mResumedActivity = null;
    }
    final ActivityState prevState = r.state;
    if (DEBUG_STATES) Slog.v(TAG, "Moving to FINISHING: " + r);
    r.state = ActivityState.FINISHING;

    if (mode == FINISH_IMMEDIATELY
            || prevState == ActivityState.STOPPED
            || prevState == ActivityState.INITIALIZING) {
        // If this activity is already stopped, we can just finish
        // it right now.
        boolean activityRemoved = destroyActivityLocked(r, true,
                oomAdj, "finish-imm");
        if (activityRemoved) {
            mStackSupervisor.resumeTopActivitiesLocked();
        }
        return activityRemoved ? null : r;
    }

    // Need to go through the full pause cycle to get this
    // activity into the stopped state and then finish it.
    mStackSupervisor.mFinishingActivities.add(r);
    mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
    return r;
}

completePauseLocked完成activity暂停的工作,这里的mPausingActivity就是当前finish的activity,由于是主动finish的,这里的prev.finishing为true,通过finishCurentActivityLocked完成暂停的工作,随后resumeTopActivitiesLocked启动当前栈顶的activity。这一部分工作在activity的启动过程有所介绍,这里不展开说明。这一流程会导致栈顶activity调用onRestart,onStart,onResume过程。我们看下acitivty执行onResume完成后会做什么。

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
    boolean reallyResume) {
    ...
    ActivityClientRecord r = performResumeActivity(token, clearHide);//回调OnResume       
    ...
    if (!r.onlyLocalRequest) {
        r.nextIdle = mNewActivities;
        mNewActivities = r;
        Looper.myQueue().addIdleHandler(new Idler());
    }
}

private class Idler implements MessageQueue.IdleHandler {
    @Override
    public final boolean queueIdle() {
        ActivityClientRecord a = mNewActivities;
        boolean stopProfiling = false;
        if (mBoundApplication != null && mProfiler.profileFd != null
                && mProfiler.autoStopProfiler) {
            stopProfiling = true;
        }
        if (a != null) {
            mNewActivities = null;
            IActivityManager am = ActivityManagerNative.getDefault();
            ActivityClientRecord prev;
            do {
                if (a.activity != null && !a.activity.mFinished) {
                    try {
                        am.activityIdle(a.token, a.createdConfig, stopProfiling);
                        a.createdConfig = null;
                    } catch (RemoteException ex) {
                        // Ignore
                    }
                }
                prev = a;
                a = a.nextIdle;
                prev.nextIdle = null;
            } while (a != null);
        }
        if (stopProfiling) {
            mProfiler.stopProfiling();
        }
        ensureJitEnabled();
        return false;
    }
}

activity处理resume过程中会在当前主线程的MessageQueue中添加一个addIdleHandler,这个handler的回调在MessageQueue中没有可以处理的消息后进行调用,而在回调中调用了AMS的activityIdle,这个方法开始处理前一个activity的finish的收尾工作。

@Override
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
    final long origId = Binder.clearCallingIdentity();
    synchronized (this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            ActivityRecord r =
                    mStackSupervisor.activityIdleInternalLocked(token, false, config);
            ...
        }
    }
    Binder.restoreCallingIdentity(origId);
}
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
            Configuration config) {
    ...
    ActivityRecord r = ActivityRecord.forToken(token);
    ...

    // Atomically retrieve all of the other things to do.
    stops = processStoppingActivitiesLocked(true);
    NS = stops != null ? stops.size() : 0;
    if ((NF=mFinishingActivities.size()) > 0) {//拷贝当前需要finish的activity
        finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
        mFinishingActivities.clear();
    }
    ...
    //处理等待finish的activities
    for (int i = 0; i < NF; i++) {
        r = finishes.get(i);
        activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");//终止activity
    }

    ...
    return r;
}
final boolean destroyActivityLocked(ActivityRecord r,
            boolean removeFromApp, boolean oomAdj, String reason) {
    ...
    boolean removedFromHistory = false;

    cleanUpActivityLocked(r, false, false);

    final boolean hadApp = r.app != null;

    if (hadApp) {
        if (removeFromApp) {
            r.app.activities.remove(r);
            if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
                mService.mHeavyWeightProcess = null;
                mService.mHandler.sendEmptyMessage(
                        ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
            }
            //如果当前APP的Activity堆栈为空了,就说明当前Activity没有可见界面了,这个时候就需要动态更新这个APP的优先级
            if (r.app.activities.isEmpty()) {
                // No longer have activities, so update LRU list and oom adj.
                mService.updateLruProcessLocked(r.app, false, null);
                mService.updateOomAdjLocked();
            }
        }

        boolean skipDestroy = false;

        try {
            r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
                    r.configChangeFlags);//通知应用端处理activity的destroy
        } 

        r.nowVisible = false;

        if (r.finishing && !skipDestroy) {
            r.state = ActivityState.DESTROYING;
            Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
            mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
        } 
        ...
    } 
    ...
    return removedFromHistory;
}

destroyActivityLocked中主要就是通知应用端进行onStop,onDestroy生命周期的回调。