美文网首页
Android Q之Activity OnStop回调时机

Android Q之Activity OnStop回调时机

作者: android_coder | 来源:发表于2019-10-14 20:30 被阅读0次

    Anroid Q 之onStop执行时机
    我们都知道在activity切换过程中,譬如A启动到BActivity,在启动完成之后一般的A会回调其onStop生命周期,那么我们就来看看何时以及何种情况下A的onStop会被回调

    1:停止Activity的流程

    1:在resume具体的activity时,当目标进程的ActivityThread的handleResumeActivity之后,会创建一个Idler,并且添加到主线程的消息队列中去

    if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
          WindowManager.LayoutParams l = r.window.getAttributes();
          if ((l.softInputMode
                & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                  != forwardBit) {
              l.softInputMode = (l.softInputMode
                        & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                        | forwardBit;
             if (r.activity.mVisibleFromClient) {
                    ViewManager wm = a.getWindowManager();
                    View decor = r.window.getDecorView();
                    wm.updateViewLayout(decor, l);
              }
            }
            r.activity.mVisibleFromServer = true;
            mNumVisibleActivities++;
            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
            }
        }
    r.nextIdle = mNewActivities;
    mNewActivities = r;
    if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
    Looper.myQueue().addIdleHandler(new Idler());------->Looper对应的是主线程的Looper,消息队列是主线程的
    

    2:handleResumeActivity执行之后已经完成了启动activity的所有动作,接下来就是Idle状态了,此时可以执行一些Idle的行为,而Idler类内部处理函数会调用activityIdle方法

    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;
                IActivityTaskManager am = ActivityTaskManager.getService();
                ActivityClientRecord prev;
                do {
                    if (localLOGV) Slog.v(
                        TAG, "Reporting idle of " + a +
                        " finished=" +
                        (a.activity != null && a.activity.mFinished));
                    if (a.activity != null && !a.activity.mFinished) {
                        try {
                            am.activityIdle(a.token, a.createdConfig, stopProfiling);---->调用activityIdle方法
                            a.createdConfig = null;
                        } catch (RemoteException ex) {
                            throw ex.rethrowFromSystemServer();
                        }
                    }
                    prev = a;
                    a = a.nextIdle;
                    prev.nextIdle = null;
                } while (a != null);
         }
         if (stopProfiling) {
                mProfiler.stopProfiling();
         }
         applyPendingProcessState();
         return false;
        }
    }
    

    3:activityIdle的具体实现

    进入到ActivityTaskManagerService.java

    @Override
    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
        final long origId = Binder.clearCallingIdentity();
        try {
            WindowProcessController proc = null;
            synchronized (mGlobalLock) {
                ActivityStack stack = ActivityRecord.getStackLocked(token);--->根据token获取对应的Stack
                if (stack == null) {
                    return;
                }
                final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
                        false /* fromTimeout */, false /* processPausingActivities */, config);
                if (r != null) {
                    proc = r.app;
                }
                if (stopProfiling && proc != null) {
                    proc.clearProfilerIfNeeded();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }
    

    4:ActivityStackSuperVisor的activityIdleInternalLocked

    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
            boolean processPausingActivities, Configuration config) {
        ......................................
        ActivityRecord r = ActivityRecord.forTokenLocked(token);----->获取ActivityRecord对象
        if (r != null) {
            if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
                    + Debug.getCallers(4));
            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
            r.finishLaunchTickingLocked();
            if (fromTimeout) {
                reportActivityLaunchedLocked(fromTimeout, r, INVALID_DELAY,
                        -1 /* launchState */);
            }
    
            // This is a hack to semi-deal with a race condition
            // in the client where it can be constructed with a
            // newer configuration from when we asked it to launch.
            // We'll update with whatever configuration it now says
            // it used to launch.
            if (config != null) {
                r.setLastReportedGlobalConfiguration(config);
            }
    
            // We are now idle.  If someone is waiting for a thumbnail from
            // us, we can now deliver.
            r.idle = true;
    
            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
    
            // Check if able to finish booting when device is booting and all resumed activities
            // are idle.
            if ((mService.isBooting() && mRootActivityContainer.allResumedActivitiesIdle())
                    || fromTimeout) {
                booting = checkFinishBootingLocked();
            }
    
            // When activity is idle, we consider the relaunch must be successful, so let's clear
            // the flag.
            r.mRelaunchReason = RELAUNCH_REASON_NONE;
        }
    
        if (mRootActivityContainer.allResumedActivitiesIdle()) {
            if (r != null) {
                mService.scheduleAppGcsLocked();
            }
    
            if (mLaunchingActivityWakeLock.isHeld()) {
                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
                if (VALIDATE_WAKE_LOCK_CALLER &&
                        Binder.getCallingUid() != Process.myUid()) {
                    throw new IllegalStateException("Calling must be system uid");
                }
                mLaunchingActivityWakeLock.release();
            }
            mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
        }
    
        // Atomically retrieve all of the other things to do.
        final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
                true /* remove */, processPausingActivities);----------->处理stopping状态的activity
        NS = stops != null ? stops.size() : 0;
        if ((NF = mFinishingActivities.size()) > 0) {
            finishes = new ArrayList<>(mFinishingActivities);
            mFinishingActivities.clear();
        }
    
        if (mStartingUsers.size() > 0) {
            startingUsers = new ArrayList<>(mStartingUsers);
            mStartingUsers.clear();
        }
    
        // Stop any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NS; i++) {
            r = stops.get(i);
            final ActivityStack stack = r.getActivityStack();
            if (stack != null) {
                if (r.finishing) {----------------->如果正处于finishing状态
                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
                            "activityIdleInternalLocked");
                } else {
                    stack.stopActivityLocked(r);------->停止该activity
                }
            }
        }
    
        // 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);----------------------------------------->处理finish状态的activity
            final ActivityStack stack = r.getActivityStack();
            if (stack != null) {
                activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
            }
        }
    
        if (!booting) {
            // Complete user switch
            if (startingUsers != null) {
                for (int i = 0; i < startingUsers.size(); i++) {
                    mService.mAmInternal.finishUserSwitch(startingUsers.get(i));
                }
            }
        }
    
        mService.mH.post(() -> mService.mAmInternal.trimApplications());
        //dump();
        //mWindowManager.dump();
    
        if (activityRemoved) {
            mRootActivityContainer.resumeFocusedStacksTopActivities();
        }
    
        return r;
    }
    

    5:ActivityStack之stopActivityLocked

    final void stopActivityLocked(ActivityRecord r) {
        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
        //如果intent中有FLAG_ACTIVITY_NO_HISTORY获取ActivityInfo中有FLAG_NO_HISTORY
        那么调用requestFinishActivityLocked销毁该activity,也就是说如果从A---->B--->C,
        如果B包含该flag,那么从C直接返回到了A
        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
            if (!r.finishing) {
                if (!shouldSleepActivities()) {
                    if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
                    if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "stop-no-history", false)) {
                        // If {@link requestFinishActivityLocked} returns {@code true},
                        // {@link adjustFocusedActivityStack} would have been already called.
                        r.resumeKeyDispatchingLocked();
                        return;
                    }
                } else {
                    if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r
                            + " on stop because we're just sleeping");
                }
            }
        }
    
        if (r.attachedToProcess()) {----->如果r的进程和主线程都存在
            adjustFocusedActivityStack(r, "stopActivity");---->调整焦点activity
            r.resumeKeyDispatchingLocked();---------->暂时允许r接受事件
            try {
                r.stopped = false;
                if (DEBUG_STATES) Slog.v(TAG_STATES,
                        "Moving to STOPPING: " + r + " (stop requested)");
                r.setState(STOPPING, "stopActivityLocked");---->设置成stopping状态
                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                        "Stopping visible=" + r.visible + " for " + r);
                if (!r.visible) {
                    r.setVisible(false);----->设置成不可见
                }
                EventLogTags.writeAmStopActivity(
                        r.mUserId, System.identityHashCode(r), r.shortComponentName);
                //事务StopActivityItem
                mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken,
                        StopActivityItem.obtain(r.visible, r.configChangeFlags));
                if (shouldSleepOrShutDownActivities()) {
                    r.setSleeping(true);
                }
                Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);----->设置超时消息
                mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
            } catch (Exception e) {
                // Maybe just ignore exceptions here...  if the process
                // has crashed, our death notification will clean things
                // up.
                Slog.w(TAG, "Exception thrown during pause", e);
                // Just in case, assume it to be stopped.
                r.stopped = true;
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
                r.setState(STOPPED, "stopActivityLocked");
                if (r.deferRelaunchUntilPaused) {
                    destroyActivityLocked(r, true, "stop-except");
                }
            }
        }
    }
    

    6:LifecycleManager处理scheduleTransaction

    这里我们在activity启动过程中已经分析过,最终调用的ActivityLifecycleItem的execute方法

    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
        client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions,
                true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");---->回调ActivityThread的handleStopActivity方法
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
    

    7:ActivityThread的handleStopActivity

     public void handleStopActivity(IBinder token, boolean show, int configChanges,
            PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
        final ActivityClientRecord r = mActivities.get(token);
        r.activity.mConfigChangeFlags |= configChanges;
    
        final StopInfo stopInfo = new StopInfo();
        performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
                reason);-------------------------->会回调onStop方法
    
        if (localLOGV) Slog.v(
            TAG, "Finishing stop of " + r + ": show=" + show
            + " win=" + r.window);
    
        updateVisibility(r, show);----------------------->更新可见性
    
        // Make sure any pending writes are now committed.
        if (!r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }
    
        stopInfo.setActivity(r);
        stopInfo.setState(r.state);
        stopInfo.setPersistentState(r.persistentState);
        pendingActions.setStopInfo(stopInfo);
        mSomeActivitiesChanged = true;
    }
    

    8:performStopActivityInner

    private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
            boolean saveState, boolean finalStateRequest, String reason) {
        if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
        if (r != null) {
            if (!keepShown && r.stopped) {
                if (r.activity.mFinished) {------------------------------->如果已经stopped了,不做处理
                    // If we are finishing, we won't call onResume() in certain
                    // cases.  So here we likewise don't want to call onStop()
                    // if the activity isn't resumed.
                    return;
                }
                if (!finalStateRequest) {
                    final RuntimeException e = new RuntimeException(
                            "Performing stop of activity that is already stopped: "
                                    + r.intent.getComponent().toShortString());
                    Slog.e(TAG, e.getMessage(), e);
                    Slog.e(TAG, r.getStateString());
                }
            }
    
            // One must first be paused before stopped...
            performPauseActivityIfNeeded(r, reason);----------------->先onPause,该方法是判断是否需要onPause
    
            if (info != null) {
                try {
                    // First create a thumbnail for the activity...
                    // For now, don't create the thumbnail here; we are
                    // doing that by doing a screen snapshot.
                    info.setDescription(r.activity.onCreateDescription());
                } catch (Exception e) {
                    if (!mInstrumentation.onException(r.activity, e)) {
                        throw new RuntimeException(
                                "Unable to save state of activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
                    }
                }
            }
    
            if (!keepShown) {--------------------------------->如果不需要保持可见,那么才回调
                callActivityOnStop(r, saveState, reason);
            }
        }
    }
    

    9:callActivityOnStop

    private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
        // Before P onSaveInstanceState was called before onStop, starting with P it's
        // called after. Before Honeycomb state was always saved before onPause.
        final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
                && !r.isPreHoneycomb();
        final boolean isPreP = r.isPreP();
        if (shouldSaveState && isPreP) {
            callActivityOnSaveInstanceState(r);--------------------->保存状态
        }
    
        try {
            r.activity.performStop(r.mPreserveWindow, reason);------>回调activity的onStop方法
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException(
                        "Unable to stop activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
            }
        }
        r.setState(ON_STOP);---------------------------------------->保存状态值
    
        if (shouldSaveState && !isPreP) {
            callActivityOnSaveInstanceState(r);
        }
    }
    

    总结

    1:pause发生在目标Activity启动之前,stop发生在目标Activity启动之后

    2:被调方式不同,pause是ams有意调用的,stop则是无意调用的。onStop不一定会回调,取决于其是否可见

    相关文章

      网友评论

          本文标题:Android Q之Activity OnStop回调时机

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