当前位置: 首页 > news >正文

dedecms图片网站模板vi设计流程

dedecms图片网站模板,vi设计流程,深圳网站建设深icp备,附近短期电脑培训班该系列文章总纲链接#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 说明#xff1a; 说明#xff1a;本章节主要解读AMS通过startActivity启动Activity的整个流程的补充#xff0c;更新了startActivity流程分析部分。 一般来说#xff0c;有Activ…该系列文章总纲链接专题总纲目录 Android Framework 总纲 本章关键点总结 说明 说明本章节主要解读AMS通过startActivity启动Activity的整个流程的补充更新了startActivity流程分析部分。 一般来说有Activity启动就有Activity退到后台。那么后者这个操作具体是怎样的呢我们以startPausingLocked方法和stopActivityLocked方法为入口分别对到activity的onPause和AMS到onStop流程进行分析。 该部分是AMS.startActivity运行中生命周期的补充毕竟startActivity关注onCreate、onStart、onResume 但activity的生命周期还涉及onPause、onStop、onDestroy。本章主要介绍onPause、onStop。最后以onStop为例介绍了下APP中回调超时的设计理念。 1 startPausingLocked方法解读onPause处理 在之前AMS.startActivity的流程分析中执行resume相关操作时就已经开始执行startPausingLocked方法了。startPausingLocked的调用入口是resume相关函数代码如下所示 //ActivityStack//关键流程step1final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {// 检查是否已经在执行恢复顶部 Activity 的操作防止递归调用if (mStackSupervisor.inResumeTopActivity) {return false; // 如果已经在执行恢复操作则直接返回 false}// 初始化结果变量用于记录恢复操作是否成功boolean result false;try {// 设置一个标志表示正在执行恢复顶部 Activity 的操作防止递归mStackSupervisor.inResumeTopActivity true;//锁屏状态相关处理//...//关键方法调用内部方法实际执行恢复顶部 Activity 的操作result resumeTopActivityInnerLocked(prev, options);} finally {// 恢复完成后重置正在执行恢复操作的标志mStackSupervisor.inResumeTopActivity false;}// 返回恢复操作的结果return result;}//关键流程step2final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen();//... boolean dontWaitForPause (next.info.flagsActivityInfo.FLAG_RESUME_WHILE_PAUSING) ! 0;boolean pausing mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);if (mResumedActivity ! null) {pausing | startPausingLocked(userLeaving, false, true, dontWaitForPause);}if (pausing) {if (next.app ! null next.app.thread ! null) {mService.updateLruProcessLocked(next.app, true, null);}return true;}//...return true;} 这里调用了startPausingLocked方法当新启动一个activity时系统将先处理当前的activity即调用该方法来pause当前activity代码实现如下 //ActivityStackfinal boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,boolean dontWait) {// 如果已经在暂停一个 Activity完成暂停操作。if (mPausingActivity ! null) {completePauseLocked(false);}// 记录当前处于前台的 Activity。ActivityRecord prev mResumedActivity;// 如果没有前台 Activity且不是正在恢复状态尝试恢复顶层 Activity。if (prev null) {if (!resuming) {mStackSupervisor.resumeTopActivitiesLocked();}return false; // 如果没有前台 Activity返回 false。}// 如果当前 Activity 没有父 Activity暂停所有子栈。if (mActivityContainer.mParentActivity null) {mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);}// 将当前前台 Activity 设置为 null准备暂停。mResumedActivity null;// 标记 prev 为正在暂停的 Activity。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 Activity 的状态为 PAUSING。prev.state ActivityState.PAUSING;// 更新任务的活动时间。prev.task.touchActiveTime();// 清除启动时间。clearLaunchTime(prev);// 获取顶层运行的 Activity。final ActivityRecord next mStackSupervisor.topRunningActivityLocked();// 如果支持最近任务并且下一个 Activity 为空或者不显示或者不在同一个任务或者 UI 休眠则更新缩略图。if (mService.mHasRecents (next null || next.noDisplay || next.task ! prev.task || uiSleeping)) {prev.updateThumbnailLocked(screenshotActivities(prev), null);}// 停止完全绘制的跟踪可能是性能监控的一部分。stopFullyDrawnTraceIfNeeded();// 更新 CPU 统计信息。mService.updateCpuStats();// 如果 prev 的应用和线程不为空发送暂停 Activity 的请求。if (prev.app ! null prev.app.thread ! null) {try {mService.updateUsageStats(prev, false);// 关键方法调用当前Activity所在进程的schedulePauseActivity方法prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving, prev.configChangeFlags, dontWait);} catch (Exception e) {// 异常处理代码省略。}} else {// 如果应用或线程为空清除暂停的 Activity 记录。mPausingActivity null;mLastPausedActivity null;mLastNoHistoryActivity null;}// 如果系统不是在休眠或关闭状态获取启动锁。if (!mService.isSleepingOrShuttingDown()) {mStackSupervisor.acquireLaunchWakelock();}// 如果正在暂停一个 Activity处理是否等待暂停完成。if (mPausingActivity ! null) {if (!uiSleeping) {// 如果 UI 不在休眠状态暂停按键分发。prev.pauseKeyDispatchingLocked();}if (dontWait) {// 如果不需要等待完成暂停并返回 false。completePauseLocked(false);return false;} else {// 如果需要等待发送暂停超时的消息并设置超时时间。Message msg mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);msg.obj prev;prev.pauseTime SystemClock.uptimeMillis();mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);return true;}} else {// 如果没有 Activity 正在暂停尝试恢复顶层 Activity。if (!resuming) {mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);}return false;}} startPausingLocked 方法用于处理 Activity 的暂停逻辑。它首先检查是否有正在进行的暂停操作如果有则完成它。然后它检查是否有前台 Activity如果没有则尝试恢复顶层 Activity。如果有前台 Activity它会更新一些状态和变量准备暂停操作。如果系统支持最近任务并且条件满足它会更新 Activity 的缩略图。然后注意关键点来了它发送一个暂停 Activity 的请求到应用线程。如果系统不是在休眠或关闭状态它会获取一个启动锁。最后根据是否需要等待暂停完成它要么立即返回要么设置一个超时消息来处理暂停超时情况。这个方法返回一个布尔值表示是否成功启动了暂停操作。 接下来关注schedulePauseActivity方法实现主要是通过消息处理最后调用handlePauseActivity方法过程中的代码实现如下 //ActivityThread//ApplicationThreadpublic 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);}//...//Handler消息处理private class H extends Handler {public void handleMessage(Message msg) {switch (msg.what) {//...case PAUSE_ACTIVITY:handlePauseActivity((IBinder)msg.obj, false, (msg.arg11) ! 0, msg.arg2,(msg.arg12) ! 0);maybeSnapshot();break;//...}}//...}//...private void handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) {// 根据 token 查找对应的 ActivityClientRecord 对象。ActivityClientRecord r mActivities.get(token);// 如果找到了对应的 ActivityClientRecord。if (r ! null) {if (userLeaving) { // 如果用户正在离开 Activity执行相关的处理。performUserLeavingActivity(r);}r.activity.mConfigChangeFlags | configChanges;// 关键方法执行暂停 Activity 的操作。performPauseActivity(token, finished, r.isPreHoneycomb());// 如果应用的 target SDK 版本低于 Honeycomb3.0等待所有队列工作完成。if (r.isPreHoneycomb()) {QueuedWork.waitToFinish();}// 如果不应该报告 Activity 暂停跳过报告步骤。if (!dontReport) {try {// 关键方法向 ActivityManager 报告 Activity 已暂停。ActivityManagerNative.getDefault().activityPaused(token);} catch (RemoteException ex) {//...}}mSomeActivitiesChanged true;}} 这里开始我们关注关键方法performPauseActivity和通知AMS做其他处理的操作。详细解读如下。 1.1 performPauseActivity方法解读 接下来一条路线是为了启动activity并调用activity的onPause方法关键方法为 //ActivityThread//关键流程step1final Bundle performPauseActivity(IBinder token, boolean finished,boolean saveState) {ActivityClientRecord r mActivities.get(token);return r ! null ? performPauseActivity(r, finished, saveState) : null;}//关键流程step2final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,boolean saveState) {try {// 如果 Activity 没有完成即没有调用过 finish()并且需要保存状态则调用 onSaveInstanceState()。if (!r.activity.mFinished saveState) {callCallActivityOnSaveInstanceState(r);}// 标记 Activity 为已调用 onPause() 状态。r.activity.mCalled false;// 调用 Activity 的 onPause() 方法。mInstrumentation.callActivityOnPause(r.activity);} catch (SuperNotCalledException e) {//...}// 标记 Activity 为已暂停状态。r.paused true;// 获取所有注册的 onPaused 监听器这些监听器将在 Activity 暂停时被通知。ArrayListOnActivityPausedListener listeners;synchronized (mOnPauseListeners) {listeners mOnPauseListeners.remove(r.activity);}// 获取监听器列表的大小。int size (listeners ! null ? listeners.size() : 0);// 遍历所有监听器调用它们的 onPaused() 方法。for (int i 0; i size; i) {listeners.get(i).onPaused(r.activity);}// 如果 Activity 没有完成并且需要保存状态则返回保存的状态 Bundle否则返回 null。return !r.activity.mFinished saveState ? r.state : null;} 这里较为简单主要就是调用activty的onPause方法了(mInstrumentation.callActivityOnPause)。另一条路线是调用完通知AMS。接下来看看通知AMS都干了些啥。 1.2 通知AMS处理Pause的相关操作 在handlePauseActivity中最后部分执ActivityManagerNative.getDefault().activityPaused(token);调用到activityPaused方法代码实现如下 //ActivityManagerService//...Overridepublic final void activityPaused(IBinder token) {final long origId Binder.clearCallingIdentity();synchronized(this) {// 根据提供的 token 查找对应的 ActivityStack。ActivityStack stack ActivityRecord.getStackLocked(token);if (stack ! null) {// 关键方法传递 token 和 false。stack.activityPausedLocked(token, false);}}Binder.restoreCallingIdentity(origId);} 这里主要关注activityPausedLocked方法的实现代码实现如下 //ActivityStack//关键流程step1final void activityPausedLocked(IBinder token, boolean timeout) {// 根据提供的 token 查找对应的 ActivityRecordfinal ActivityRecord r isInStackLocked(token);if (r ! null) {// 从消息队列中移除任何与 PAUSE_TIMEOUT_MSG 相关的消息避免暂停超时mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);// 如果当前正在暂停的 Activity 与找到的 ActivityRecord 相匹配if (mPausingActivity r) {// 关键方法完成暂停操作传递 truecompletePauseLocked(true);}//...}}//关键流程step2private void completePauseLocked(boolean resumeNext) {// 获取当前正在暂停的 ActivityRecordActivityRecord prev mPausingActivity;if (prev ! null) {// 将 Activity 的状态设置为 PAUSEDprev.state ActivityState.PAUSED;// 如果 Activity 正在结束则调用 finishCurrentActivityLocked 方法完成结束操作if (prev.finishing) {prev finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);} else if (prev.app ! null) { // 如果 Activity 关联的应用不为空// 如果 Activity 正在等待可见状态则更新状态并从等待列表中移除if (prev.waitingVisible) {prev.waitingVisible false;mStackSupervisor.mWaitingVisibleActivities.remove(prev);}// 如果需要销毁 Activity则调用 destroyActivityLocked 方法if (prev.configDestroy) {destroyActivityLocked(prev, true, pause-config);} else if (!hasVisibleBehindActivity()) { // 如果没有可见的后置 Activity// 将当前 Activity 添加到停止的 Activity 列表中mStackSupervisor.mStoppingActivities.add(prev);// 根据条件决定是否调度空闲状态if (mStackSupervisor.mStoppingActivities.size() 3 ||prev.frontOfTask mTaskHistory.size() 1) {mStackSupervisor.scheduleIdleLocked();} else {mStackSupervisor.checkReadyForSleepLocked();}}} else {prev null;}// 清空正在暂停的 ActivitymPausingActivity null;}// 如果需要恢复下一个 Activityif (resumeNext) {final ActivityStack topStack mStackSupervisor.getFocusedStack();// 如果服务没有进入休眠或关闭状态恢复顶层 Activityif (!mService.isSleepingOrShuttingDown()) {mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);} else {// 检查是否准备好进入休眠状态mStackSupervisor.checkReadyForSleepLocked();ActivityRecord top topStack.topRunningActivityLocked(null);// 如果顶层 Activity 为空或与当前暂停的 Activity 不同恢复顶层 Activityif (top null || (prev ! null top ! prev)) {mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);}}}// 如果 prev 不为空恢复按键分发if (prev ! null) {prev.resumeKeyDispatchingLocked();//电池信息统计}// 通知任务栈发生了变化mService.notifyTaskStackChangedLocked();} completePauseLocked 方法用于完成 Activity 的pause操作。它首先更新 Activity 的状态并处理与应用相关的各种情况包括销毁、停止和恢复下一个 Activity。方法还处理 CPU 使用情况的更新并在 Activity 状态变化时通知系统。这个方法确保了 Activity 在暂停时能够正确地保存状态和资源同时为下一个 Activity 的恢复做好准备。 但是注意这里涉及老activity的pause和新activity的resume操作相信第一次看的伙伴并不容易理解因此这里使用一个案例来帮忙理解。 1.3 场景案例解读completePauseLocked 这里使用一个场景案例来解读所谓的completePauseLocked在逻辑上到底是干了啥便于理解。当使用 am 命令从 Launcher 界面启动一个 Settings Activity 时Android 系统会经历以下步骤。每个步骤详细解读如下。 1.3.1 启动 Settings Activity 系统通过 ActivityManagerService 的 startActivity() 方法启动新的 Settings Activity。 ActivityManagerService 负责协调启动过程包括创建新的 Activity 记录ActivityRecord和调度启动。 1.3.2 Launcher 的 onPause() 调用 在新的 Settings Activity 变得可见之前当前的 Launcher Activity 需要进入暂停paused状态。 ActivityManagerService 会通知 Launcher Activity 调用它的 onPause() 生命周期方法。 这是通过 completePauseLocked() 方法完成的该方法会更新 Launcher Activity 的状态为 PAUSED 并执行相关的暂停操作。 1.3.3 Settings Activity 的 onCreate() 和 onStart() 调用 随着新的 Settings Activity 被创建它的 onCreate() 和 onStart() 生命周期方法会被调用。 这些方法负责初始化 Activity设置 UI以及准备显示内容。 1.3.4 Settings Activity 的 onResume() 调用 一旦 Settings Activity 准备好显示它的 onResume() 方法会被调用。 onResume() 方法标志着 Activity 变得可见并开始与用户交互。 1.3.5 completePauseLocked() 中的逻辑 如果 completePauseLocked() 方法被调用它会处理 Launcher Activity 的暂停逻辑。 这包括调用 Launcher Activity 的 onPause() 方法更新系统状态以及准备恢复下一个 Activity。 如果 resumeNext 参数为 truecompletePauseLocked() 方法会请求 ActivityManagerService 恢复下一个 Activity即 Settings Activity。 1.3.6 Settings Activity 的恢复 在 Launcher Activity 暂停后ActivityManagerService 会负责恢复 Settings Activity。 这涉及到调用 Settings Activity 的 onResume() 方法使其成为前台 Activity。 总结来说在这种场景下completePauseLocked() 方法主要负责处理 Launcher Activity 的暂停逻辑而 Settings Activity 的 onResume() 方法会在 Launcher Activity 暂停后被调用以确保用户体验的连续性和响应性。这个过程是由 ActivityManagerService 协调。 2 stopActivityLocked方法onStop处理 2.1 找到stopActivityLocked调用的入口Idler stopActivityLocked藏的比较深接下来我们从handleResumeActivity开始。想更多了解可参考文 章Android Framework AMS05startActivity分析-2(ActivityThread启动到Activity拉起)文中 2.2.2 对handleResumeActivity方法有详细的解读本次我们关注点不同handleResumeActivity 关键代码解读如下 //ActivityThreadfinal void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {unscheduleGcIdler(); // 取消垃圾回收的定时器准备恢复 ActivitymSomeActivitiesChanged true; // 标记有 Activity 状态改变// 关键方法resume Activity 的操作ActivityClientRecord r performResumeActivity(token, clearHide); if (r ! null) {//...if (!r.onlyLocalRequest) {r.nextIdle mNewActivities; // 设置下一个空闲的 ActivitymNewActivities r; // 设置新的 ActivityLooper.myQueue().addIdleHandler(new Idler()); // 添加空闲处理器}r.onlyLocalRequest false; // 清除本地请求标志if (reallyResume) {try {ActivityManagerNative.getDefault().activityResumed(token); // 通知 AMS Activity 已resume} catch (RemoteException ex) {}}} else {//...}} 这里我们主要关注一句话 Looper.myQueue().addIdleHandler(new Idler()); 接下来我们对这句话进行详细解读 Looper.myQueue()获取当前线程的消息队列。在 Android 中每个线程都有自己的消息队列而主线程的消息队列是处理 UI 更新和生命周期回调的核心。Looper 对象与消息队列关联负责循环处理队列中的消息。addIdleHandler()向消息队列添加一个空闲处理器IdleHandler。空闲处理器是一种特殊的回调接口它在消息队列中没有消息时被调用即在消息队列空闲时触发。new Idler()创建一个新的 Idler 实例。Idler 是 IdleHandler 接口的一个实现它定义了在消息队列空闲时执行的操作。 这行代码的设计目的是为了在主线程空闲时进行垃圾回收和其他优化操作。通过这种方式系统可以在不影响 UI 性能的情况下做一些事情比如提高资源利用率减少内存泄漏优化电池使用并提供更平滑的用户体验。这是 Android 系统中一个重要的性能优化机制。 当消息队列中没有消息时Idler 会被调用更具体地说IdleHandler 的 queueIdle 方法将会被调用。接下里我们看该方法的实现代码如下 //ActivityThread//IdlerOverridepublic final boolean queueIdle() {//activity列表含义最近被启动但还没有报告为空闲idle的 Activity 实例ActivityClientRecord a mNewActivities;boolean stopProfiling false;//性能相关处理//...if (a ! null) { // 如果存在新的 Activity 记录// 清空 mNewActivities 链表准备处理这些 ActivitymNewActivities null;IActivityManager am ActivityManagerNative.getDefault();ActivityClientRecord prev;do {// 如果 Activity 存在且没有finishif (a.activity ! null !a.activity.mFinished) {try {// 通知 AMSActivity 已经空闲am.activityIdle(a.token, a.createdConfig, stopProfiling);// 清空创建配置表示已经处理a.createdConfig null;} catch (RemoteException ex) {//...}}// 记录当前 Activity 记录然后移动到下一个prev a;a a.nextIdle;// 断开当前记录的下一个引用避免内存泄漏prev.nextIdle null;} while (a ! null);}//...ensureJitEnabled();// 返回false 表示不再需要这个IdleHandler将其从消息队列中移除return false;} 这个方法主要用于处理消息队列空闲时的一些操作这组 ActivityClientRecord 列表代表了那些需要进一步处理或状态更新的 Activity 实例。它们在消息队列空闲时被处理通知 AMS 某个 Activity 已经空闲。这些操作都是在 UI 线程没有其他工作时完成的这样可以确保不会影响用户界面的响应性。activityIdle代码实现如下 //ActivityManagerServiceOverridepublic 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);} 继续分析ActivityStackSupervisor.activityIdleInternalLocked方法的实现代码如下 //ActivityStackSupervisorfinal ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,Configuration config) {ArrayListActivityRecord stops null;ArrayListActivityRecord finishes null;ArrayListUserStartedState startingUsers null;int NS 0; // 停止activity的计数int NF 0; // 结束activity的计数boolean booting false; // 标记系统是否正在启动boolean activityRemoved false; // 标记是否有activity被移除// 根据 token 获取对应的 ActivityRecord 对象ActivityRecord r ActivityRecord.forToken(token);if (r ! null) {mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);r.finishLaunchTickingLocked();// 如果是因为超时导致的空闲报告activity已启动// 针对stop的分析这里fromTimeoutfalseif (fromTimeout) {reportActivityLaunchedLocked(fromTimeout, r, -1, -1);}if (config ! null) {r.configuration config;}r.idle true;// 标记 Activity 为空闲状态// 如果 Activity 位于前台栈或者是因为超时检查是否完成启动if (isFrontStack(r.task.stack) || fromTimeout) {booting checkFinishBootingLocked();}}// 如果所有恢复的activity都处于空闲状态调度应用程序的垃圾回收if (allResumedActivitiesIdle()) {if (r ! null) {mService.scheduleAppGcsLocked();}// 如果有activity正在启动并且被暂停移除相关的消息并释放if (mLaunchingActivity.isHeld()) {mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);//...mLaunchingActivity.release();}// 确保activity可见ensureActivitiesVisibleLocked(null, 0);}// 处理所有标记为停止的activitystops processStoppingActivitiesLocked(true);NS stops ! null ? stops.size() : 0;// 如果有等待完成的activity将它们添加到列表中并清空原列表if ((NFmFinishingActivities.size()) 0) {finishes new ArrayListActivityRecord(mFinishingActivities);mFinishingActivities.clear();}// 如果有正在启动的用户将它们添加到列表中并清空原列表if (mStartingUsers.size() 0) {startingUsers new ArrayListUserStartedState(mStartingUsers);mStartingUsers.clear();}// 停止所有标记为停止的activityfor (int i 0; i NS; i) {r stops.get(i);final ActivityStack stack r.task.stack;if (r.finishing) {// 如果activity正在完成立即结束它stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);} else {//关键方法stop activity操作stack.stopActivityLocked(r);}}// 完成所有标记为结束的activityfor (int i 0; i NF; i) {r finishes.get(i);// 如果activity被移除标记 activityRemoved 为 trueactivityRemoved | r.task.stack.destroyActivityLocked(r, true, finish-idle);}// 如果系统不在启动过程中完成用户启动if (!booting) {if (startingUsers ! null) {for (int i 0; i startingUsers.size(); i) {mService.finishUserSwitch(startingUsers.get(i));}}if (mStartingBackgroundUsers.size() 0) {startingUsers new ArrayListUserStartedState(mStartingBackgroundUsers);mStartingBackgroundUsers.clear();for (int i 0; i startingUsers.size(); i) {mService.finishUserBoot(startingUsers.get(i));}}}// 修剪应用程序释放无用资源mService.trimApplications();// 如果有activity被移除恢复顶层activityif (activityRemoved) {resumeTopActivitiesLocked();}return r;} 至此终于看到stopActivityLocked操作了。接下来我们以分析此方法为主。 2.2 stopActivityLocked方法解读onStop处理 stopActivityLocked方法的实现代码如下 //ActivityStackfinal void stopActivityLocked(ActivityRecord r) {// 如果 Activity 在其 intent 或 activity info 中被标记为没有历史记录即不在后退栈中出现if ((r.intent.getFlags()Intent.FLAG_ACTIVITY_NO_HISTORY) ! 0|| (r.info.flagsActivityInfo.FLAG_NO_HISTORY) ! 0) {// 如果 Activity 还没有结束if (!r.finishing) {// 如果系统没有在睡眠状态if (!mService.isSleeping()) {// 请求结束这个 Activity并传递一个取消的结果码requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, no-history, false);}}}// 如果 Activity 的应用和线程不为空if (r.app ! null r.app.thread ! null) {// 调整焦点 ActivityadjustFocusedActivityLocked(r, stopActivity);// 恢复分派按键事件r.resumeKeyDispatchingLocked();try {// 重置 Activity 的 stopped 状态r.stopped false;// 更新 Activity 的状态为 STOPPINGr.state ActivityState.STOPPING;// 如果 Activity 不可见通知窗口管理器if (!r.visible) {mWindowManager.setAppVisibility(r.appToken, false);}// 关键方法通过应用线程请求停止 Activityr.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);// 如果系统正在睡眠或关闭设置 Activity 为睡眠状态if (mService.isSleepingOrShuttingDown()) {r.setSleeping(true);}// 获取一个消息对象并将其发送到消息队列如果 Activity 停止操作超时将处理该消息Message msg mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);} catch (Exception e) {// 异常处理省略}}} stopActivityLocked 负责停止一个 Activity。它首先检查 Activity 是否被标记为没有历史记录如果是并且 Activity 还没有结束且系统不在睡眠状态它会请求结束这个 Activity。接下来如果 Activity 的应用和线程不为空它会调整焦点 Activity恢复按键分派更新 Activity 的状态为 STOPPING并请求应用线程停止这个 Activity这里较为关键。如果系统正在睡眠或关闭它会设置 Activity 为睡眠状态。最后它会发送一个延迟消息用于处理停止操作的超时情况。 接下来我们关注关键方法ActivityThread.scheduleStopActivity的实现代码如下 //ActivityThread//ApplicationThreadpublic final void scheduleStopActivity(IBinder token, boolean showWindow,int configChanges) {sendMessage(showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,token, 0, configChanges);}//...//Handler消息处理private class H extends Handler {public void handleMessage(Message msg) {switch (msg.what) {//...case STOP_ACTIVITY_SHOW:handleStopActivity((IBinder)msg.obj, true, msg.arg2);break;//...}}//...}//...private void handleStopActivity(IBinder token, boolean show, int configChanges) {ActivityClientRecord r mActivities.get(token);r.activity.mConfigChangeFlags | configChanges;StopInfo info new StopInfo();// 执行停止 Activity 的内部操作performStopActivityInner(r, info, show, true);// 更新 Activity 的可见性状态updateVisibility(r, show);//...// 安排在 UI 线程上告诉 Activity Manager 我们已经停止了 Activity// 我们不是立即这样做因为我们希望在通知 Activity Manager 之前// 有机会完成任何其他挂起的工作特别是内存修剪请求然后才能让应用完全进入后台info.activity r;info.state r.state;info.persistentState r.persistentState;mH.post(info);mSomeActivitiesChanged true; // 标记有 Activity 状态改变} 这里继续分析performStopActivityInner方法的实现代码如下 //ActivityThreadprivate void performStopActivityInner(ActivityClientRecord r,StopInfo info, boolean keepShown, boolean saveState) {if (r ! null) {//...// 如果 Activity 没有完成即没有调用过 finish()并且需要保存状态if (!r.activity.mFinished saveState) {// 如果 Activity 的状态对象为空调用 onSaveInstanceState() 方法来保存状态if (r.state null) {callCallActivityOnSaveInstanceState(r);}}// 如果 Activity 不需要保持显示状态if (!keepShown) {try {// 调用 Activity 的 performStop() 方法来执行停止操作r.activity.performStop();} catch (Exception e) {// ...}r.stopped true;// 标记 Activity 为已停止状态}r.paused true;// 标记 Activity 为已暂停状态}} performStopActivityInner 负责执行 Activity 的停止操作。它首先检查 Activity 是否需要保持显示状态。如果不需要并且 Activity 之前没有被停止过它会执行停止操作。如果需要保存状态它会调用 onSaveInstanceState() 方法来保存 Activity 的状态。最后它调用 Activity 的performStop() 方法来执行实际的停止操作并更新 Activity 的状态为已停止和已暂停。performStop方法实现代码如下 //Activityfinal void performStop() {// 标记不再需要报告完全绘制状态mDoReportFullyDrawn false;// 如果加载器已经开始现在需要停止它们if (mLoadersStarted) {mLoadersStarted false; // 标记加载器已停止// 如果有加载器管理器根据配置更改情况执行停止或保留操作if (mLoaderManager ! null) {if (!mChangingConfigurations) {mLoaderManager.doStop(); // 停止加载器} else {mLoaderManager.doRetain(); // 保留加载器}}}// 如果 Activity 之前没有被停止过if (!mStopped) {// 如果有窗口对象关闭所有面板if (mWindow ! null) {mWindow.closeAllPanels();}// 如果 Activity 有 token 且没有父 Activity通知窗口管理器该 Activity 已停止if (mToken ! null mParent null) {WindowManagerGlobal.getInstance().setStoppedState(mToken, true);}// 分发 Fragment 的停止事件mFragments.dispatchStop();// 标记未调用 onStop()mCalled false;//关键方法该方法间接调用 Activity 的 onStop() 方法mInstrumentation.callActivityOnStop(this);//光标处理相关//...mStopped true;// 标记 Activity 为已停止状态}mResumed false;// 标记 Activity 不再处于 resume 状态} performStop() 方法执行了 onStop() 生命周期方法之后的操作包括停止 Loader关闭窗口面板更新 Fragment 的状态释放数据库和光标资源以及更新 Activity 的状态。这个方法确保了在 Activity 停止时所有资源都被正确管理和释放以避免内存泄漏和其他资源问题。此外它还确保了 onStop() 方法被正确调用如果没有会抛出异常。最后更新了 Activity 的状态以反映它不再处于 resume 状态。 至此调用到activity的onStop方法了(mInstrumentation.callActivityOnStop)。有了onPause和onStop的分析方法感兴趣的伙伴可以自行分析下onDestroy的流程。这里不再编写该部分。 3 超时设计的解读 这里的超时的设计以Activity的onStop超时处理为例。即2.2 中stopActivityLocked方法为例解读下onStop的超时处理流程整理后相关代码如下 //ActivityStackfinal void stopActivityLocked(ActivityRecord r) {//...// 如果 Activity 的应用和线程不为空if (r.app ! null r.app.thread ! null) {//...try {//...// 关键方法通过应用线程请求停止 Activityr.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);//...// 获取一个消息对象并将其发送到消息队列如果 Activity 停止操作超时将处理该消息Message msg mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);} catch (Exception e) {// 异常处理省略}}} 可以看到执行scheduleStopActivity后开始用handler发送延迟消息。注意这里是不管是否延迟都会发消息。那么消息是在哪里处理的呢 我们以scheduleStopActivity为入口进行分析。这里scheduleStopActivity通过handler发送消息最终由handleStopActivity来处理我们就从handleStopActivity这个方法开始分析代码整理后关键代码如下 //ActivityThreadprivate void handleStopActivity(IBinder token, boolean show, int configChanges) {ActivityClientRecord r mActivities.get(token);r.activity.mConfigChangeFlags | configChanges;StopInfo info new StopInfo();performStopActivityInner(r, info, show, true);//...updateVisibility(r, show);//...//这里开始通过post执行info的run方法info.activity r;info.state r.state;info.persistentState r.persistentState;mH.post(info);mSomeActivitiesChanged true;} 这里主要关注StopInfo的实现及run方法因为post会导致run的调用StopInfo代码如下 private static class StopInfo implements Runnable {ActivityClientRecord activity;Bundle state;PersistableBundle persistentState;CharSequence description;Override public void run() {try {ActivityManagerNative.getDefault().activityStopped(activity.token, state, persistentState, description);} catch (RemoteException ex) {}}} 继续分析AMS的关键方法activityStopped的实现代码如下 //ActivityManagerServiceOverridepublic final void activityStopped(IBinder token, Bundle icicle,PersistableBundle persistentState, CharSequence description) {//...final long origId Binder.clearCallingIdentity();synchronized (this) {ActivityRecord r ActivityRecord.isInStackLocked(token);if (r ! null) {r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);}}trimApplications();Binder.restoreCallingIdentity(origId);} 继续分析这里的关键方法activityStoppedLocked的实现整理关键代码内容分析代码如下 //ActivityStackfinal void activityStoppedLocked(ActivityRecord r, Bundle icicle,PersistableBundle persistentState, CharSequence description) {if (r.state ! ActivityState.STOPPING) {Slog.i(TAG, Activity reported stop, but no longer stopping: r);mHandler.removeMessages(STOP_TIMEOUT_MSG, r);return;}//...} 如果一切正常那么最后会通过AMS在ActivityStack的activityStoppedLocked中将这个超时消息移除。也就是正常情况下只要不超过这个超时的时间都会正常运行出现超时的异常情况会导致延迟消息未取消而正常发送导致异常处理的流程。 以上是以onStop的流程未基础进行分析其他的onCreate、onStart、onResume、onPause等也是按照类似方式来处理超时的。
文章转载自:
http://www.morning.gmyhq.cn.gov.cn.gmyhq.cn
http://www.morning.ygqhd.cn.gov.cn.ygqhd.cn
http://www.morning.tnthd.cn.gov.cn.tnthd.cn
http://www.morning.mqdr.cn.gov.cn.mqdr.cn
http://www.morning.tkyxl.cn.gov.cn.tkyxl.cn
http://www.morning.wrlxy.cn.gov.cn.wrlxy.cn
http://www.morning.rkmsm.cn.gov.cn.rkmsm.cn
http://www.morning.xtyyg.cn.gov.cn.xtyyg.cn
http://www.morning.mqxzh.cn.gov.cn.mqxzh.cn
http://www.morning.yqqxj1.cn.gov.cn.yqqxj1.cn
http://www.morning.mcjrf.cn.gov.cn.mcjrf.cn
http://www.morning.nkqnn.cn.gov.cn.nkqnn.cn
http://www.morning.rkzk.cn.gov.cn.rkzk.cn
http://www.morning.hcqd.cn.gov.cn.hcqd.cn
http://www.morning.bryyb.cn.gov.cn.bryyb.cn
http://www.morning.syglx.cn.gov.cn.syglx.cn
http://www.morning.dsmwy.cn.gov.cn.dsmwy.cn
http://www.morning.cwwts.cn.gov.cn.cwwts.cn
http://www.morning.wtdyq.cn.gov.cn.wtdyq.cn
http://www.morning.qdsmile.cn.gov.cn.qdsmile.cn
http://www.morning.lizpw.com.gov.cn.lizpw.com
http://www.morning.tymnr.cn.gov.cn.tymnr.cn
http://www.morning.grbp.cn.gov.cn.grbp.cn
http://www.morning.spsqr.cn.gov.cn.spsqr.cn
http://www.morning.ztrht.cn.gov.cn.ztrht.cn
http://www.morning.hffpy.cn.gov.cn.hffpy.cn
http://www.morning.tdmgs.cn.gov.cn.tdmgs.cn
http://www.morning.hlwzd.cn.gov.cn.hlwzd.cn
http://www.morning.jlxqx.cn.gov.cn.jlxqx.cn
http://www.morning.zwsgl.cn.gov.cn.zwsgl.cn
http://www.morning.zymgs.cn.gov.cn.zymgs.cn
http://www.morning.jfjbl.cn.gov.cn.jfjbl.cn
http://www.morning.jgnst.cn.gov.cn.jgnst.cn
http://www.morning.zqwp.cn.gov.cn.zqwp.cn
http://www.morning.tfpqd.cn.gov.cn.tfpqd.cn
http://www.morning.ywzqk.cn.gov.cn.ywzqk.cn
http://www.morning.flxqm.cn.gov.cn.flxqm.cn
http://www.morning.cgtfl.cn.gov.cn.cgtfl.cn
http://www.morning.yrrnx.cn.gov.cn.yrrnx.cn
http://www.morning.qbjrl.cn.gov.cn.qbjrl.cn
http://www.morning.czrcf.cn.gov.cn.czrcf.cn
http://www.morning.lhldx.cn.gov.cn.lhldx.cn
http://www.morning.mwns.cn.gov.cn.mwns.cn
http://www.morning.hnhsym.cn.gov.cn.hnhsym.cn
http://www.morning.kcnjz.cn.gov.cn.kcnjz.cn
http://www.morning.hwlmy.cn.gov.cn.hwlmy.cn
http://www.morning.mzpd.cn.gov.cn.mzpd.cn
http://www.morning.duqianw.com.gov.cn.duqianw.com
http://www.morning.rfkyb.cn.gov.cn.rfkyb.cn
http://www.morning.bqfpm.cn.gov.cn.bqfpm.cn
http://www.morning.cwpny.cn.gov.cn.cwpny.cn
http://www.morning.mdmxf.cn.gov.cn.mdmxf.cn
http://www.morning.ryrpq.cn.gov.cn.ryrpq.cn
http://www.morning.ptwrz.cn.gov.cn.ptwrz.cn
http://www.morning.rryny.cn.gov.cn.rryny.cn
http://www.morning.skkln.cn.gov.cn.skkln.cn
http://www.morning.rmxgk.cn.gov.cn.rmxgk.cn
http://www.morning.dhqzc.cn.gov.cn.dhqzc.cn
http://www.morning.kxrld.cn.gov.cn.kxrld.cn
http://www.morning.jhgxh.cn.gov.cn.jhgxh.cn
http://www.morning.gnjkn.cn.gov.cn.gnjkn.cn
http://www.morning.znlhc.cn.gov.cn.znlhc.cn
http://www.morning.wdnkp.cn.gov.cn.wdnkp.cn
http://www.morning.xyrw.cn.gov.cn.xyrw.cn
http://www.morning.tknqr.cn.gov.cn.tknqr.cn
http://www.morning.zqmdn.cn.gov.cn.zqmdn.cn
http://www.morning.kjlhb.cn.gov.cn.kjlhb.cn
http://www.morning.jmmzt.cn.gov.cn.jmmzt.cn
http://www.morning.ygrkg.cn.gov.cn.ygrkg.cn
http://www.morning.ymwcs.cn.gov.cn.ymwcs.cn
http://www.morning.pxlql.cn.gov.cn.pxlql.cn
http://www.morning.pabxcp.com.gov.cn.pabxcp.com
http://www.morning.spghj.cn.gov.cn.spghj.cn
http://www.morning.xjkfb.cn.gov.cn.xjkfb.cn
http://www.morning.fbrshjf.com.gov.cn.fbrshjf.com
http://www.morning.xwrhk.cn.gov.cn.xwrhk.cn
http://www.morning.jtsdk.cn.gov.cn.jtsdk.cn
http://www.morning.dhqzc.cn.gov.cn.dhqzc.cn
http://www.morning.wtnwf.cn.gov.cn.wtnwf.cn
http://www.morning.mtcnl.cn.gov.cn.mtcnl.cn
http://www.tj-hxxt.cn/news/271574.html

相关文章:

  • 校园网站开发的目的网站蓝色配色
  • 58同城承德网站建设权重查询爱站网
  • 宛城区微网站建设wordpress query vars
  • 财经网站模板建站网站免费
  • 淄博乐达信息技术网站做网站的几个必要步骤
  • wordpress手机端如何做优化排名会不会影响网站速度
  • 河南海华工程建设监理公司网站dedecms行业门户网站模板
  • 深圳企业网站设网站语言
  • 郑州公司网站开发广东企业网站建设哪家好
  • 深圳免费模板建站wordpress自定义注册页面
  • 网站开发的相关网站python网站开发招聘
  • 设计深圳网站制作南通网站开发
  • 漳州做网站最便宜陕西省住房建设厅官方网站
  • 缔烨建设公司网站沈阳做网站优化的公司哪家好
  • ppt课件免费下载的网站马鞍山网站建设专业制
  • 婚庆网站开发的意义管理咨询师考试
  • 网站做sem能够提高收录量吗怎么做会员自动售卡网站
  • 如何做网站架构广州家居网站设计
  • 域名如何做网站单机网页小游戏
  • t恤在线设计网站如何制作app网站
  • 朵朵软件网站建设开发网站和application
  • 有什么网站开发客户网站空间运行挂机宝
  • 建设企业网站的申请网站监控 重启
  • 网站域名备案 更改吗许昌市建设信息网站
  • 自己做的网站显示不全网站建设客户源
  • 网站与建设实训报告西峰网站建设
  • 泊头做网站电话网站首页的动态怎么做
  • 黄冈网站推广厂家php文件打开乱码
  • 枣庄建设工程管理局网站自己房子做民宿挂什么网站
  • 网站制作哪家好又便宜运营一款app的费用