博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android Activity启动过程(三)从栈顶Activity的onPause到启动activityon的Resume过程
阅读量:5217 次
发布时间:2019-06-14

本文共 16938 字,大约阅读时间需要 56 分钟。

ActivityStack.startPausingLocked() 

IApplicationThread.schudulePauseActivity() 
ActivityThread.sendMessage() 
ActivityThread.H.sendMessage(); 
ActivityThread.H.handleMessage() 
ActivityThread.handlePauseActivity() 
ActivityThread.performPauseActivity() 
Activity.performPause() 
Activity.onPause() 
ActivityManagerNative.getDefault().activityPaused(token) 
ActivityManagerService.activityPaused() 
ActivityStack.activityPausedLocked() 
ActivityStack.completePauseLocked() 
ActivityStack.resumeTopActivitiesLocked() 
ActivityStack.resumeTopActivityLocked() 
ActivityStack.resumeTopActivityInnerLocked() 
ActivityStack.startSpecificActivityLocked 

final class ActivityStack {     ...    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {        ...        if (mResumedActivity != null) {            if (DEBUG_STATES) Slog.d(TAG_STATES,                    "resumeTopActivityLocked: Pausing " + mResumedActivity);            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);        }        ...        return true;    }        final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,            boolean dontWait) {        if (mPausingActivity != null) {            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity);            completePauseLocked(false);        }        ActivityRecord prev = mResumedActivity;        if (prev == null) {            if (!resuming) {                Slog.wtf(TAG, "Trying to pause when nothing is resumed");                mStackSupervisor.resumeTopActivitiesLocked();            }            return false;        }        ...        if (prev.app != null && prev.app.thread != null) {            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);            try {                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,                        prev.userId, System.identityHashCode(prev),                        prev.shortComponentName);                mService.updateUsageStats(prev, false);                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,                        userLeaving, prev.configChangeFlags, dontWait);            } 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;        }        ...    }    ...}

这里执行了pre.app.thread.schedulePauseActivity方法。这里prev是一个ActivityRecord 

 
final class ActivityRecord {ProcessRecord app;      // if non-null, hosting application...}

这里APP是一个ProcessRecord 

final class ProcessRecord {IApplicationThread thread; // the actual proc... may be null only if...}

通过分析不难发现这里的thread是一个IApplicationThread

 主要是一个接口

public interface IApplicationThread extends IInterface {    void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,            int configChanges, boolean dontReport) throws RemoteException;    void scheduleStopActivity(IBinder token, boolean showWindow,            int configChanges) throws RemoteException;    void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;    void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;    void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)            throws RemoteException;    void scheduleSendResult(IBinder token, List
results) throws RemoteException; void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List
pendingResults, List
pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException; void scheduleRelaunchActivity(IBinder token, List
pendingResults, List
pendingNewIntents, int configChanges, boolean notResumed, Configuration config) throws RemoteException; void scheduleNewIntent(List
intent, IBinder token) throws RemoteException; void scheduleDestroyActivity(IBinder token, boolean finished, int configChanges) throws RemoteException; void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, boolean sync, int sendingUser, int processState) throws RemoteException; ....}

public final class ActivityThread {    final ApplicationThread mAppThread = new ApplicationThread();    final H mH = new H();        private void sendMessage(int what, Object obj) {        sendMessage(what, obj, 0, 0, false);    }    private void sendMessage(int what, Object obj, int arg1) {        sendMessage(what, obj, arg1, 0, false);    }    private void sendMessage(int what, Object obj, int arg1, int arg2) {        sendMessage(what, obj, arg1, arg2, false);    }    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {        if (DEBUG_MESSAGES) Slog.v(            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)            + ": " + arg1 + " / " + obj);        Message msg = Message.obtain();        msg.what = what;        msg.obj = obj;        msg.arg1 = arg1;        msg.arg2 = arg2;        if (async) {            msg.setAsynchronous(true);        }        mH.sendMessage(msg);    }          private class H extends Handler {          ...                  public void handleMessage(Message msg) {            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));            switch (msg.what) {                case LAUNCH_ACTIVITY: {                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;                    r.packageInfo = getPackageInfoNoCheck(                            r.activityInfo.applicationInfo, r.compatInfo);                    handleLaunchActivity(r, null);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                } break;                case RELAUNCH_ACTIVITY: {                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;                    handleRelaunchActivity(r);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                } break;                case PAUSE_ACTIVITY:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");                    handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,                            (msg.arg1&2) != 0);                    maybeSnapshot();                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case PAUSE_ACTIVITY_FINISHING:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");                    handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,                            (msg.arg1&1) != 0);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case STOP_ACTIVITY_SHOW:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");                    handleStopActivity((IBinder)msg.obj, true, msg.arg2);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case STOP_ACTIVITY_HIDE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");                    handleStopActivity((IBinder)msg.obj, false, msg.arg2);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                    ...        }      }    ...}

 

而在ActivityThread中也定义了一个的类,其继承了IApplicationThread,并且都是Binder对象,

不难看出这里的IApplicationThread是一个Binder的client端

而ActivityThread中的是一个Binder对象的server端,

所以通过这里的thread.schedulePauseActivity实际上调用的就是ApplicationThread的schedulePauseActivity方法

 

这里的ApplicationThread可以和ActivityManagerNative对于一下: 

通过ActivityManagerNative –> ActivityManagerService实现了应用进程与SystemServer进程的通讯 
通过AppicationThread <– IApplicationThread实现了SystemServer进程与应用进程的通讯

 是ActivityThread的内部类

private class ApplicationThread extends ApplicationThreadNative {                ...        public final void schedulePauseActivity(IBinder token, boolean finished,                boolean userLeaving, int configChanges, boolean dontReport) {            sendMessage(                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,                    token,                    (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),                    configChanges);        }        public final void scheduleStopActivity(IBinder token, boolean showWindow,                int configChanges) {           sendMessage(                showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,                token, 0, configChanges);        }            public final void scheduleResumeActivity(IBinder token, int processState,                boolean isForward, Bundle resumeArgs) {            updateProcessState(processState, false);            sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);        }        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,                ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,                IVoiceInteractor voiceInteractor, int procState, Bundle state,                PersistableBundle persistentState, List
pendingResults, List
pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); r.token = token; ... sendMessage(H.LAUNCH_ACTIVITY, r); } ... }

 schedulePauseActivity是在内部类中调用ActivityThread的sendMessage()

最终调用了mH的sendMessage方法,mH是在ActivityThread中定义的一个Handler对象(主要处理SystemServer进程的消息)

Handler在handleMessage()可以发现其调用了handlePauseActivity方法

 

#handlePauseActivity

private void handlePauseActivity(IBinder token, boolean finished,            boolean userLeaving, int configChanges, boolean dontReport) {        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());            // Make sure any pending writes are now committed.            if (r.isPreHoneycomb()) {                QueuedWork.waitToFinish();            }            // Tell the activity manager we have paused.            if (!dontReport) {                try {                    ActivityManagerNative.getDefault().activityPaused(token);                } catch (RemoteException ex) {                }            }            mSomeActivitiesChanged = true;        }    }

在方法体内部通过调用performPauseActivity方法来实现对栈顶Activity的onPause生命周期方法的回调,可以具体看一下他的实现:

final Bundle performPauseActivity(IBinder token, boolean finished,            boolean saveState) {        ActivityClientRecord r = mActivities.get(token);        return r != null ? performPauseActivity(r, finished, saveState) : null;    }final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,            boolean saveState) {        ...        mInstrumentation.callActivityOnPause(r.activity);        ...        return !r.activity.mFinished && saveState ? r.state : null;    }

 回到了mInstrumentation的callActivityOnPuase方法:

public void callActivityOnPause(Activity activity) {        activity.performPause();    }

final void performPause() {        mDoReportFullyDrawn = false;        mFragments.dispatchPause();        mCalled = false;        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;    }

回调到了Activity的onPause方法,也就是说我们在启动一个Activity的时候最先被执行的是栈顶的Activity的onPause方法。

然后回到我们的handlePauseActivity方法,在该方法的最后面执行了ActivityManagerNative.getDefault().activityPaused(token);方法,这是应用进程告诉服务进程,栈顶Activity已经执行完成onPause方法了,通过前面我们的分析,我们知道这句话最终会被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);    }

 该方法内部会调用ActivityStack的activityPausedLocked方法

final void activityPausedLocked(IBinder token, boolean timeout) {            ...                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r                        + (timeout ? " (due to timeout)" : " (pause complete)"));                completePauseLocked(true);            ...    }  private void completePauseLocked(boolean resumeNext) {        ...        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.                    mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);                }            }

 经过了一系列的逻辑之后,又调用了resumeTopActivitiesLocked方法,又回到了第二步中解析的方法中了,这样经过 

resumeTopActivitiesLocked –> 
ActivityStack.resumeTopActivityLocked() –> 
resumeTopActivityInnerLocked –> 
startSpecificActivityLocked 

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

可以发现在这个方法中,首先会判断一下需要启动的Activity所需要的应用进程是否已经启动,若启动的话,则直接调用realStartAtivityLocked方法,否则调用startProcessLocked方法,用于启动应用进程。 

这样关于启动Activity时的第三步骤就已经执行完成了,这里主要是实现了对栈顶Activity执行onPause 
方法,而这个方法首先判断需要启动的Activity所属的进程是否已经启动,若已经启动则直接调用启动Activity的方法,否则将先启动Activity的应用进程,然后在启动该Activity

转载于:https://www.cnblogs.com/mingfeng002/p/9155401.html

你可能感兴趣的文章
jenkins+testNG
查看>>
[洛谷1485] 火枪打怪
查看>>
PAT B1018.锤子剪刀布(20)
查看>>
Extjs控件之 grid打印功能
查看>>
枚举类型(不常用)递归
查看>>
ETL
查看>>
Tomcat源码分析(六)--日志记录器和国际化
查看>>
YII缓存依赖的应用
查看>>
决策树在机器学习的理论学习与实践
查看>>
Biee 11g权限详解
查看>>
minggw 安装
查看>>
Jquery操作cookie,实现简单的记住用户名的操作
查看>>
[BZOJ1196][HNOI2006]公路修建问题 二分答案+最小生成树
查看>>
PHP基础入门(二)
查看>>
[Luogu P3119] [USACO15JAN]草鉴定Grass Cownoisseur (缩点+图上DP)
查看>>
【原创】大数据基础之Zookeeper(4)应用场景
查看>>
18款在线代码片段测试工具
查看>>
20.C++- &&,||逻辑重载操作符的缺陷、,逗号重载操作符的分析
查看>>
静态变量数组实现LRU算法
查看>>
在SQL中怎么把一列字符串拆分为多列
查看>>