自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android源碼進階之ActivityRecord、TaskRecord、ActivityStack以及啟動模式詳細分析

移動開發(fā) Android
activity啟動時候會說到activity棧,任務棧,activity任務棧等詞語,但是如果細問這些名詞的代表著什么?以什么表現形式出現?

[[420066]]

前言

activity啟動時候會說到activity棧,任務棧,activity任務棧等詞語,但是如果細問這些名詞的代表著什么?以什么表現形式出現?

一個ActivityRecord對應一個Activity,保存了一個Activity的所有信息;但是一個Activity可能會有多個ActivityRecord,因為Activity可以被多次啟動,這個主要取決于其啟動模式;

一個TaskRecord由一個或者多個ActivityRecord組成,這就是我們常說的任務棧,具有后進先出的特點;

ActivityStack則是用來管理TaskRecord的,包含了多個TaskRecord;

今天我們就來聊聊怎么管理activity以及任務棧等;

一、任務棧源碼解析

1、ActivityRecord

ActivityRecord:歷史棧中的一個條目,代表一個activity

  1. final class ActivityRecord extends ConfigurationContainer implements AppWindowContainerListener { 
  2.         final ActivityManagerService service; // owner 
  3.         final IApplicationToken.Stub appToken; // window manager token 
  4.         AppWindowContainerController mWindowContainerController; 
  5.         final ActivityInfo info; // all about me 
  6.         final ApplicationInfo appInfo; // information about activity's app 
  7.         //省略其他成員變量 
  8.         //ActivityRecord所在的TaskRecord 
  9.         private TaskRecord task;        // the task this is in
  10.         //構造方法,需要傳遞大量信息 
  11.         ActivityRecord(ActivityManagerService _service, ProcessRecord _caller, int _launchedFromPid, 
  12.                        int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType, 
  13.                        ActivityInfo aInfo, Configuration _configuration, 
  14.                        com.android.server.am.ActivityRecord _resultTo, String _resultWho, int _reqCode, 
  15.                        boolean _componentSpecified, boolean _rootVoiceInteraction, 
  16.                        ActivityStackSupervisor supervisor, ActivityOptions options, 
  17.                        com.android.server.am.ActivityRecord sourceRecord) { 
  18.         } 
  19.     } 
  • 實際上,ActivityRecord中存在著大量的成員變量,包含了一個Activity的所有信息;
  • ActivityRecord中的成員變量task表示其所在的TaskRecord,由此可以看出:ActivityRecord與TaskRecord建立了聯系;

startActivity()時會創(chuàng)建一個ActivityRecord

  1. class ActivityStarter { 
  2.         private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, 
  3.                                   String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, 
  4.                                   IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 
  5.                                   IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, 
  6.                                   String callingPackage, int realCallingPid, int realCallingUid, int startFlags, 
  7.                                   ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, 
  8.                                   com.android.server.am.ActivityRecord[] outActivity, TaskRecord inTask) { 
  9.             //其他代碼略 
  10.             ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, 
  11.                     callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), 
  12.                     resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null
  13.                     mSupervisor, options, sourceRecord); 
  14.             //其他代碼略 
  15.         } 
  16.     } 

2、TaskRecord

TaskRecord,內部維護一個ArrayList用來保存ActivityRecord;

  1. final class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener { 
  2.         final int taskId;       //任務ID 
  3.         final ArrayList<ActivityRecord> mActivities;   //使用一個ArrayList來保存所有的ActivityRecord 
  4.         private ActivityStack mStack;   //TaskRecord所在的ActivityStack 
  5.         //構造方法 
  6.         TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent, 
  7.                    IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, int type) { 
  8.         } 
  9.         //添加Activity到頂部 
  10.         void addActivityToTop(com.android.server.am.ActivityRecord r) { 
  11.             addActivityAtIndex(mActivities.size(), r); 
  12.         } 
  13.         //添加Activity到指定的索引位置 
  14.         void addActivityAtIndex(int index, ActivityRecord r) { 
  15.             //... 
  16.             r.setTask(this);//為ActivityRecord設置TaskRecord,就是這里建立的聯系 
  17.             //... 
  18.             index = Math.min(sizeindex); 
  19.             mActivities.add(index, r);//添加到mActivities 
  20.             //... 
  21.         } 
  22.         //其他代碼略 
  23.     } 
  • 可以看到TaskRecord中使用了一個ArrayList來保存所有的ActivityRecord;
  • 同樣,TaskRecord中的mStack表示其所在的ActivityStack;

startActivity()時也會創(chuàng)建一個TaskRecord;

  1. class ActivityStarter { 
  2.         private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate, int preferredLaunchStackId, ActivityStack topStack) { 
  3.             mTargetStack = computeStackFocus(mStartActivity, true, mLaunchBounds, mLaunchFlags, mOptions); 
  4.             if (mReuseTask == null) { 
  5.                 //創(chuàng)建一個createTaskRecord,實際上是調用ActivityStack里面的createTaskRecord()方法,ActivityStack下面會講到 
  6.                 final TaskRecord task = mTargetStack.createTaskRecord( 
  7.                         mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), 
  8.                         mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, 
  9.                         mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession, 
  10.                         mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity.mActivityType); 
  11.                 //其他代碼略 
  12.             } 
  13.         } 
  14.     } 

3、ActivityStack

ActivityStack,內部維護了一個ArrayList,用來管理TaskRecord;

  1. class ActivityStack<T extends StackWindowController> extends ConfigurationContainer implements StackWindowListener { 
  2.         private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();//使用一個ArrayList來保存TaskRecord 
  3.         final int mStackId; 
  4.         protected final ActivityStackSupervisor mStackSupervisor;//持有一個ActivityStackSupervisor,所有的運行中的ActivityStacks都通過它來進行管理 
  5.         //構造方法 
  6.         ActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId, 
  7.                       ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) { 
  8.         } 
  9.         TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, 
  10.                                     IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 
  11.                                     boolean toTop, int type) { 
  12.             //創(chuàng)建一個task 
  13.             TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession, voiceInteractor, type); 
  14.             //將task添加到ActivityStack中去 
  15.             addTask(task, toTop, "createTaskRecord"); 
  16.             //其他代碼略 
  17.             return task; 
  18.         } 
  19.         //添加Task 
  20.         void addTask(final TaskRecord task, final boolean toTop, String reason) { 
  21.             addTask(task, toTop ? MAX_VALUE : 0, true /* schedulePictureInPictureModeChange */, reason); 
  22.             //其他代碼略 
  23.         } 
  24.         //添加Task到指定位置 
  25.         void addTask(final TaskRecord task, int position, boolean schedulePictureInPictureModeChange, 
  26.                      String reason) { 
  27.             mTaskHistory.remove(task);//若存在,先移除 
  28.             //... 
  29.             mTaskHistory.add(position, task);//添加task到mTaskHistory 
  30.             task.setStack(this);//為TaskRecord設置ActivityStack 
  31.             //... 
  32.         } 
  33.         //其他代碼略 
  34.     } 
  • 看到ActivityStack使用了一個ArrayList來保存TaskRecord;
  • 另外,ActivityStack中還持有ActivityStackSupervisor對象,這個是用來管理ActivityStacks的;
  • ActivityStack是由ActivityStackSupervisor來創(chuàng)建的,實際ActivityStackSupervisor就是用來管理ActivityStack的,繼續(xù)看下面的ActivityStackSupervisor分析;

4、ActivityStackSupervisor

ActivityStackSupervisor,顧名思義,就是用來管理ActivityStack的;

  1. ActivityStackSupervisor,顧名思義,就是用來管理ActivityStack的; 
  2.     public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener { 
  3.         ActivityStack mHomeStack;//管理的是Launcher相關的任務 
  4.         ActivityStack mFocusedStack;//管理非Launcher相關的任務 
  5.         //創(chuàng)建ActivityStack 
  6.         ActivityStack createStack(int stackId, ActivityStackSupervisor.ActivityDisplay display, boolean onTop) { 
  7.             switch (stackId) { 
  8.                 case PINNED_STACK_ID: 
  9.                     //PinnedActivityStack是ActivityStack的子類 
  10.                     return new PinnedActivityStack(display, stackId, this, mRecentTasks, onTop); 
  11.                 default
  12.                     //創(chuàng)建一個ActivityStack 
  13.                     return new ActivityStack(display, stackId, this, mRecentTasks, onTop); 
  14.             } 
  15.         } 
  16.     } 
  • ActivityStackSupervisor內部有兩個不同的ActivityStack對象:mHomeStack、mFocusedStack,用來管理不同的任務;
  • ActivityStackSupervisor內部包含了創(chuàng)建ActivityStack對象的方法;
  • AMS初始化時會創(chuàng)建一個ActivityStackSupervisor對象;

二、啟動流程和啟動模式看任務棧

1、啟動流程

啟動Activity過程中涉及到的ActivityStack、TaskRecord、ActivityRecord、ActivityStackSupervisor進行簡單的分析,實際上一張時序圖就可以看明白了

  • startActivity時首先會創(chuàng)建一個ActivityRecord。
  • 如果有需要,會創(chuàng)建一個TaskRecord,并把這個TaskRecord加入到ActivityStack中。
  • 將ActivityRecord添加到TaskRecord的棧頂

2、啟動模式中的任務棧

①standerd

默認模式,每次啟動Activity都會創(chuàng)建一個新的Activity實例

現在有個A Activity,我們在A上面啟動B,再然后在B上面啟動A,其過程如圖所示

②singleTop

  • 如果要啟動的Activity已經在棧頂,則不會重新創(chuàng)建Activity,只會調用該該Activity的onNewIntent()方法。
  • 如果要啟動的Activity不在棧頂,則會重新創(chuàng)建該Activity的實例;

現在有個A Activity,我們在A以standerd模式上面啟動B,然后在B上面以singleTop模式啟動A,其過程如圖所示,這里會新創(chuàng)建一個A實例

B上面以singleTop模式啟動B的話,則不會重新創(chuàng)建B,只會調用onNewIntent()方法,其過程如圖所示

③singleTask

  • 如果要啟動的Activity已經存在于它想要歸屬的棧中,那么不會創(chuàng)建該Activity實例,將棧中位于該Activity上的所有的Activity出棧,同時該Activity的onNewIntent()方法會被調用。
  • 如果要啟動的Activity不存在于它想要歸屬的棧中,并且該棧存在,則會創(chuàng)建該Activity的實例。
  • 如果要啟動的Activity想要歸屬的棧不存在,則首先要創(chuàng)建一個新棧,然后創(chuàng)建該Activity實例并壓入到新棧中

現在有個A Activity,我們在A以standerd模式上面啟動B,然后在B上面以singleTask模式啟動A,其過程如圖所示

④singleInstance

基本和singleTask一樣,不同的是啟動Activity時,首先要創(chuàng)建在一個新棧,然后創(chuàng)建該Activity實例并壓入新棧中,新棧中只會存在這一個Activity實例;

現在有個A Activity,我們在A以singleInstance模式上面啟動B,其過程如圖所示:

3、啟動Flag

startActivity()時往Intent 中加入相應的標志來指定啟動模式,這種方式的優(yōu)先級會比在AndroidManifest中定義的優(yōu)先級高;但是AndroidManifest中只能定義四種啟動方式:standard、singleTop、singleTask、singleInstance,而Intent的flag則有很多種。具體的可以看看文檔,我們這里看看部分flag:

  • FLAG_ACTIVITY_NEW_TASK :跟launchMode中的singleTask一樣。
  • FLAG_ACTIVITY_SINGLE_TOP :跟launchMode中的singleTop一樣。
  • FLAG_ACTIVITY_CLEAR_TOP :launchMode中沒有對應的值,如果要啟動的Activity已經存在于棧中,則將所有位于它上面的Activity出棧。singleTask默認具有此標記位的效果【責任編輯:武曉燕 TEL:(010)68476606】

 

責任編輯:武曉燕 來源: Android開發(fā)編程
相關推薦

2021-08-27 07:38:21

AndroidDialogContext

2009-03-24 09:17:58

驅動GSMAndroid

2009-03-24 08:30:54

AndroidGoogle移動os

2009-09-25 14:23:39

2009-09-28 10:39:01

Hibernate基礎

2010-02-06 15:19:35

2009-09-08 15:56:50

Linq使用Group

2009-09-14 13:50:35

LINQ編程模型

2009-11-20 13:11:44

Oracle XML數

2010-01-06 13:50:37

.NET Framew

2013-12-04 10:21:38

AndroidAndroidMani

2009-06-18 14:00:51

2009-09-09 09:48:43

Linq延遲加載

2009-10-10 13:52:57

VB Update方法

2009-09-14 16:21:34

LINQ To XML

2009-09-09 13:53:21

Linq表值函數

2009-12-03 17:41:40

PHP應用發(fā)展

2009-09-07 14:18:01

C#內存管理

2021-10-25 19:52:52

IntentFilte

2009-10-28 10:06:29

VB.NET With
點贊
收藏

51CTO技術棧公眾號