zoukankan      html  css  js  c++  java
  • android Activity启动过程(三)从栈顶Activity的onPause到启动activityon的Resume过程

    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 

    ActivityStack.java

    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 

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

    这里APP是一个ProcessRecord 

    ProcessRecord.java

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

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

    IApplicationThread.java 主要是一个接口

    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<ResultInfo> 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<ResultInfo> pendingResults,
                List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                ProfilerInfo profilerInfo) throws RemoteException;
        void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
                List<Intent> pendingNewIntents, int configChanges,
                boolean notResumed, Configuration config) throws RemoteException;
        void scheduleNewIntent(List<Intent> 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;
                ....
    }

    ActivityThread.java

    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中也定义了一个ApplicationThread的类,其继承了IApplicationThread,并且都是Binder对象,

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

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

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

    这里的ApplicationThread可以和ActivityManagerNative对于一下: 
    通过ActivityManagerNative –> ActivityManagerService实现了应用进程与SystemServer进程的通讯 
    通过AppicationThread <– IApplicationThread实现了SystemServer进程与应用进程的通讯

    ActivityThread.java#ApplicationThread 是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<ResultInfo> pendingResults,
                    List<Intent> 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方法

    ActivityThread.java#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生命周期方法的回调,可以具体看一下他的实现:

     

    ActivityThread.java#performPauseActivity

    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方法:

    Instrumentation.java#callActivityOnPause

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

    Activity.java#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方法执行。

    ActivityManagerService.java#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方法

    ActivityStack.java#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

  • 相关阅读:
    影院售票系统
    返璞归真
    【C++】【STL】【map】基础知识干货
    书签-技术类
    正则表达式-正则表达式校验金额最多保留两位小数
    winCommand-cmd杀死进程
    idea快捷键-总结
    接口封装-泛型方法、泛型接口、lambda表达式【类似ios传递block】
    treeMap-get返回null,因为比较器出问题
    git-linux一个月更新80万行代码,如何保证项目稳健?
  • 原文地址:https://www.cnblogs.com/mingfeng002/p/9155401.html
Copyright © 2011-2022 走看看