圖解Activity啟動流程


前言

  • 基於android4.4.2源碼
  • activity 生命周期圖

    本文在講訴Activity啟動流程涉及到了一些Activity生命周期的知識,所以把官方文檔直接貼上來(附圖1),對Activity生命周期知識了然於心的大神直接無視就好。對於剛接觸android的看客,則需要先去了解這方面的知識。

  • 涉及知識

    binder機制,因本人原因只能在后續的文章才會更新這方面的內容,對這方面不了解的看客建議先去看binder機制的知識。

    android Task ,官方文檔解釋很清楚。

附圖1

  

一、Activity啟動流程

(一)在Launch發送startActivity請求

  在我們的Android系統中,應用程序是由Launch這個應用啟動起來的。當我們安裝好應用程序之后,就會在Launch的界面上生成一個圖標,我們點擊圖標時Launch就會啟動我們的應用程序。這一過程會去收集我們應用程序一些相關的信息然后通過IPC通信送到AMS。這第一大步的流程如圖1所示:

圖1

 

  1. AppsCustomizePagedView.onClick

 1 public class AppsCustomizePagedView extends PagedViewWithDraggableItems implements
 2         View.OnClickListener, View.OnKeyListener, DragSource,
 3         PagedViewIcon.PressedCallback, PagedViewWidget.ShortPressListener,
 4         LauncherTransitionable {
 5         
 6     //當在屏幕上點擊app圖標,就會調用AppsCustomizePagedView類的成員函數onClick
 7     //主要獲得app的一些相關信息然后就調用Launcher這個類的成員函數startActivitySafely
 8     public void onClick(View v) {
 9         
10         if (v instanceof PagedViewIcon) {
11             // Animate some feedback to the click
12             final ApplicationInfo appInfo = (ApplicationInfo) v.getTag();
13 
14             // Lock the drawable state to pressed until we return to Launcher
15             if (mPressedIcon != null) {
16             mPressedIcon.lockDrawableState();
17             }
18           
19             mLauncher.updateWallpaperVisibility(true);                   
20             mLauncher.startActivitySafely(v, appInfo.intent, appInfo);   // goto step 2--->
21         } else if (v instanceof PagedViewWidget) {
22            //code....
23         }
24     }
25 }

 

  2. Launcher.startActivitySafely

 1 public final class Launcher extends Activity
 2         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
 3                    View.OnTouchListener {
 4     //這個函數主要是用來把應用程序里面的AndroidManifest.xml文件中的一些配置信息保存到intent里
 5     boolean startActivitySafely(View v, Intent intent, Object tag) {            
 6         boolean success = false;
 7         try {
 8             /* intent包含的信息為 : 
 9              * action = "android.intent.action.Main",
10              * category="android.intent.category.LAUNCHER", 
11              * cmp="com.activity/.MainActivity" <---要啟動的Activity
12              */
13             success = startActivity(v, intent, tag);  //  goto step 3 --->
14         } catch (ActivityNotFoundException e) {
15             //code...
16         }
17         return success;
18     }
19 }    

 

  3. Launcher.startActivity

 1 public final class Launcher extends Activity
 2         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
 3                    View.OnTouchListener {
 4     //這個函數主要是獲得高和寬,然后調用Activity類的成員函數startActivity
 5     //因為Launcher繼承於Activity類,而Activity類實現了startActivity函數
 6     boolean startActivity(View v, Intent intent, Object tag) {                   
 7         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 8         try {
 9             boolean useLaunchAnimation = (v != null) &&
10                 !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION); // useLaunchAnimation = true
11             if (useLaunchAnimation) { //come here
12             ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
13                 v.getMeasuredWidth(), v.getMeasuredHeight());
14 
15             startActivity(intent, opts.toBundle());  //  goto step 4 --->
16             } else {            
17             startActivity(intent);
18             }
19             return true;
20         } catch (SecurityException e) {
21            //code...
22         }
23         return false;
24     }                           
25 }

 

   4. Activity.startActivity

 1 public class Activity extends ContextThemeWrapper
 2         implements LayoutInflater.Factory2,
 3         Window.Callback, KeyEvent.Callback,
 4         OnCreateContextMenuListener, ComponentCallbacks2 {
 5         
 6     //不做實事的函數,只是單純的調用startActivityForResult函數而已
 7     public void startActivity(Intent intent, Bundle options) {
 8         if (options != null) {      //come here 
 9             startActivityForResult(intent, -1, options);  //  goto step 5 --->
10         } else {            
11             startActivityForResult(intent, -1);
12         }
13     }
14 }

 

  5. Activity.startActivityForResult

 1 public class Activity extends ContextThemeWrapper
 2         implements LayoutInflater.Factory2,
 3         Window.Callback, KeyEvent.Callback,
 4         OnCreateContextMenuListener, ComponentCallbacks2 {
 5             
 6     public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
 7         //根據傳進來的參數,就可以把這個函數無關代碼省略
 8         //intent : pos ...
 9         //requestCode = -1
10         //options : app name ...
11         
12         if (mParent == null) {
13             /*
14              * 1. mMainThread的類型為ActivityThread,同時也是Activity類的一個變量
15              *     mMainThread.getApplicationThread() 獲得ApplicationThread成員變量,即一個Binder對象
16              *    注 : mMainThread代表的是Launcher應用程序運行的進程
17              * 2. mToken : Activity類的一個變量,是一個Binder對象的遠程接口
18              */
19             Instrumentation.ActivityResult ar =
20             mInstrumentation.execStartActivity(   //  goto step 6   --->
21                 this, mMainThread.getApplicationThread(), mToken, this,
22                 intent, requestCode, options);
23             //code...
24         } else {
25            //code...
26         }
27     }
28 }

 

  6.  Instrumentation.execStartActivity

 1 public class Instrumentation {
 2 
 3     //這個函數也可以說不做實事,只是通過IPC通信而已
 4     public ActivityResult execStartActivity(
 5             Context who, IBinder contextThread, IBinder token, Activity target,
 6             Intent intent, int requestCode, Bundle options) {
 7         IApplicationThread whoThread = (IApplicationThread) contextThread;
 8         if (mActivityMonitors != null) {
 9            //code...
10         }
11         try {
12     
13             intent.migrateExtraStreamToClipData();
14             intent.prepareToLeaveProcess();
15         
16         //ActivityManagerNative.getDefault返回ActivityManagerService的遠程接口,即ActivityManagerProxy接口
17         //target != null 
18         //target.mEmbddedID = null
19             int result = ActivityManagerNative.getDefault()                //  goto step 7  --->
20                 .startActivity(whoThread, who.getBasePackageName(), intent,
21                         intent.resolveTypeIfNeeded(who.getContentResolver()),
22                         token, target != null ? target.mEmbeddedID : null,
23                         requestCode, 0, null, null, options);
24             checkStartActivityResult(result, intent);
25         } catch (RemoteException e) {
26         }
27         return null;
28  }

 

(二)AMS接收客戶端startActivity請求

  AMS接收到Launcher請求Activity后,就對這個將要啟動的Activity進行一些相關信息的的解析及檢查,然后創建一個ActivityRecord。其流程如圖2所示:  

 

圖2

  7. ActivityManagerProxy.startActivity

 1 class ActivityManagerProxy implements IActivityManager
 2 {
 3     /* 沒什么好說的,就是把信息轉發到AMS里而已 
 4      * 1. caller : ApplicationThread類型的Binder實體
 5      * 2. resultTo : 為一個Binder實體的遠程接口
 6      * 3. resolvedType = grantedUriPermissions = resultWho = null
 7      * 4. grantedMode = 0 requestCode = -1 onlyIfNeeded = debug = false
 8      */    
 9     public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
10             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
11             int startFlags, String profileFile,
12             ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
13         Parcel data = Parcel.obtain();
14         Parcel reply = Parcel.obtain();
15         data.writeInterfaceToken(IActivityManager.descriptor);
16         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
17         data.writeString(callingPackage);
18         intent.writeToParcel(data, 0);
19         data.writeString(resolvedType);
20         data.writeStrongBinder(resultTo);
21         data.writeString(resultWho);
22         data.writeInt(requestCode);
23         data.writeInt(startFlags);
24         data.writeString(profileFile);
25         if (profileFd != null) {
26             data.writeInt(1);
27             profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
28         } else {
29             data.writeInt(0);
30         }
31         if (options != null) {
32             data.writeInt(1);
33             options.writeToParcel(data, 0);
34         } else {
35             data.writeInt(0);
36         }
37         mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
38         reply.readException();
39         int result = reply.readInt();
40         reply.recycle();
41         data.recycle();
42         return result;
43     }
44 }

 

  8. ActivityManagerService.startActivity

 1 public final class ActivityManagerService extends ActivityManagerNative
 2         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 3     //不干實事的函數,就是單純的調用ActivityManagerService.startActivityAsUser
 4     public final int startActivity(IApplicationThread caller, String callingPackage,
 5             Intent intent, String resolvedType, IBinder resultTo,
 6             String resultWho, int requestCode, int startFlags,
 7             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
 8         //  goto step 9  --->
 9         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
10             resultWho, requestCode,
11             startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
12     }          
13 }

 

  9. ActivityManagerService.startActivityAsUser

 1 public final class ActivityManagerService extends ActivityManagerNative
 2         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 3     //也是基本都做事,只是單純的調用ActivityStackSupervisor.startActivityMayWait
 4     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
 5             Intent intent, String resolvedType, IBinder resultTo,
 6             String resultWho, int requestCode, int startFlags,
 7             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
 8         
 9         enforceNotIsolatedCaller("startActivity");
10         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
11             false, true, "startActivity", null);
12 
13         //  goto step 10  --->
14         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
15             resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
16             null, null, options, userId);
17     }
18 } 

 

  10. ActivityStackSupervisor.startActivityMayWait

 1 public final class ActivityStackSupervisor {
 2 
 3     //對intent的內容進行解析,得到MainActivity的相關信息后,把其保存在aInfo
 4     final int startActivityMayWait(IApplicationThread caller, int callingUid,
 5             String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
 6             String resultWho, int requestCode, int startFlags, String profileFile,
 7             ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
 8             Bundle options, int userId) {
 9         
10         //執行完后 componentSpecified = true
11         boolean componentSpecified = intent.getComponent() != null;
12 
13         // Don't modify the client's object!
14         intent = new Intent(intent);
15             
16         //對參數intent的內容進行解析      
17         ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
18                 profileFile, profileFd, userId);
19 
20         synchronized (mService) {
21             int callingPid;
22             if (callingUid >= 0) {
23                 //code...
24             } else if (caller == null) {
25                //code...
26             } else {
27                 callingPid = callingUid = -1;
28             }
29 
30             final ActivityStack stack = getFocusedStack();
31             stack.mConfigWillChange = config != null
32                     && mService.mConfiguration.diff(config) != 0;
33            
34             final long origId = Binder.clearCallingIdentity();
35 
36             if (aInfo != null &&
37                     (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
38 
39                   //code...這里有一大段if語句的代碼,先把他省略掉
40             }        
41         
42             //  goto step 11 --->
43             int res = startActivityLocked(caller, intent, resolvedType,
44                     aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
45                     callingPackage, startFlags, options, componentSpecified, null);
46 
47             if (stack.mConfigWillChange) {            
48                 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
49                         "updateConfiguration()");
50                 stack.mConfigWillChange = false;
51                 if (DEBUG_CONFIGURATION) Slog.v(TAG,
52                         "Updating to new configuration after starting activity.");
53                 mService.updateConfigurationLocked(config, null, false, false);
54             }
55 
56             Binder.restoreCallingIdentity(origId);
57 
58             if (outResult != null) { //outResult = null 
59                 outResult.result = res;
60                 if (res == ActivityManager.START_SUCCESS) {
61                     mWaitingActivityLaunched.add(outResult);
62                     do {
63                         try {
64                             mService.wait();
65                         } catch (InterruptedException e) {
66                         }
67                     } while (!outResult.timeout && outResult.who == null);
68                 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
69                     ActivityRecord r = stack.topRunningActivityLocked(null);
70                     if (r.nowVisible) {
71                         outResult.timeout = false;
72                         outResult.who = new ComponentName(r.info.packageName, r.info.name);
73                         outResult.totalTime = 0;
74                         outResult.thisTime = 0;
75                     } else {
76                         outResult.thisTime = SystemClock.uptimeMillis();
77                         mWaitingActivityVisible.add(outResult);
78                         do {
79                             try {
80                                 mService.wait();
81                             } catch (InterruptedException e) {
82                             }
83                         } while (!outResult.timeout && outResult.who == null);
84                     }
85                 }
86             }
87 
88             return res;
89         }
90     }
91 
92 }

 

  11. ActivityStackSupervisor.startActivityLocked

  1 public final class ActivityStackSupervisor {
  2     //主要是保存Launcher的相關信息及創建一個ActivityRecord
  3     //代碼中會有一些詳細的注釋
  4     final int startActivityLocked(IApplicationThread caller,
  5             Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
  6             String resultWho, int requestCode,
  7             int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
  8             boolean componentSpecified, ActivityRecord[] outActivity) {
  9         int err = ActivityManager.START_SUCCESS;
 10 
 11         ProcessRecord callerApp = null;
 12         if (caller != null) {
 13             //獲取Launch的相關信息(pid,uid)保存到ProcessRecord變量
 14             callerApp = mService.getRecordForAppLocked(caller);
 15             if (callerApp != null) {
 16                 callingPid = callerApp.pid;
 17                 callingUid = callerApp.info.uid;
 18             } else {
 19                //code...
 20             }
 21         }
 22 
 23         if (err == ActivityManager.START_SUCCESS) {
 24             final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;           
 25         }
 26 
 27         ActivityRecord sourceRecord = null;  //表示正在執行的Activity(在當前的情景下也就是Launcher)
 28         ActivityRecord resultRecord = null;  //表示啟動將要啟動的Activity返回的結果,(在當前的情景下將要啟動的Activity就是MainActivity)
 29         if (resultTo != null) {
 30             //獲得Launcher的相關信息保存在ActivityRecord里
 31             sourceRecord = isInAnyStackLocked(resultTo);
 32                        
 33             if (sourceRecord != null) {
 34                 if (requestCode >= 0 && !sourceRecord.finishing) {
 35                     //code...
 36                 }
 37             }
 38         }
 39         
 40         ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
 41 
 42         int launchFlags = intent.getFlags();
 43 
 44         if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
 45                 && sourceRecord != null) {
 46             //code...
 47         }
 48 
 49         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
 50            //code..
 51         }
 52 
 53         if (err == ActivityManager.START_SUCCESS && aInfo == null) {
 54            //code...
 55         }
 56 
 57         if (err != ActivityManager.START_SUCCESS) {
 58             //code...
 59         }
 60 
 61         //以下一代段代碼主要是對Activity進行一序列權限的檢查
 62         final int startAnyPerm = mService.checkPermission(
 63                 START_ANY_ACTIVITY, callingPid, callingUid);
 64         final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
 65                 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
 66         if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
 67             if (resultRecord != null) {
 68                 resultStack.sendActivityResultLocked(-1,
 69                     resultRecord, resultWho, requestCode,
 70                     Activity.RESULT_CANCELED, null);
 71             }
 72             setDismissKeyguard(false);
 73             String msg;
 74             if (!aInfo.exported) {
 75                 msg = "Permission Denial: starting " + intent.toString()
 76                         + " from " + callerApp + " (pid=" + callingPid
 77                         + ", uid=" + callingUid + ")"
 78                         + " not exported from uid " + aInfo.applicationInfo.uid;
 79             } else {
 80                 msg = "Permission Denial: starting " + intent.toString()
 81                         + " from " + callerApp + " (pid=" + callingPid
 82                         + ", uid=" + callingUid + ")"
 83                         + " requires " + aInfo.permission;
 84             }
 85             Slog.w(TAG, msg);
 86             throw new SecurityException(msg);
 87         }
 88 
 89         boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
 90                 callingPid, resolvedType, aInfo.applicationInfo);
 91 
 92         if (mService.mController != null) {
 93             try {
 94                 // The Intent we give to the watcher has the extra data
 95                 // stripped off, since it can contain private information.
 96                 Intent watchIntent = intent.cloneFilter();
 97                 abort |= !mService.mController.activityStarting(watchIntent,
 98                         aInfo.applicationInfo.packageName);
 99             } catch (RemoteException e) {
100                 mService.mController = null;
101             }
102         }
103 
104         if (abort) {
105             if (resultRecord != null) {
106                 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
107                         Activity.RESULT_CANCELED, null);
108             }
109             // We pretend to the caller that it was really started, but
110             // they will just get a cancel result.
111             setDismissKeyguard(false);
112             ActivityOptions.abort(options);
113             return ActivityManager.START_SUCCESS;
114         }
115 
116         //創建一個 ActivityRecord , 包括uid,packagename,intent,ainfo,requestCode等等信息
117         ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
118                 intent, resolvedType, aInfo, mService.mConfiguration,
119                 resultRecord, resultWho, requestCode, componentSpecified, this);    
120         
121         if (outActivity != null) {
122             outActivity[0] = r;
123         }
124 
125         final ActivityStack stack = getFocusedStack();
126         if (stack.mResumedActivity == null
127                 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
128             if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
129                 PendingActivityLaunch pal =
130                         new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
131                 mService.mPendingActivityLaunches.add(pal);
132                 setDismissKeyguard(false);
133                 ActivityOptions.abort(options);
134                 return ActivityManager.START_SWITCHES_CANCELED;
135             }
136         }
137 
138         if (mService.mDidAppSwitch) {
139             // This is the second allowed switch since we stopped switches,
140             // so now just generally allow switches.  Use case: user presses
141             // home (switches disabled, switch to home, mDidAppSwitch now true);
142             // user taps a home icon (coming from home so allowed, we hit here
143             // and now allow anyone to switch again).
144             mService.mAppSwitchesAllowedTime = 0;
145         } else {
146             mService.mDidAppSwitch = true;
147         }
148 
149         mService.doPendingActivityLaunchesLocked(false);
150 
151         //  goto step 12   --->
152         err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
153 
154         if (allPausedActivitiesComplete()) {           
155             dismissKeyguard();
156         }
157         return err;
158     }
159 }

 

(三)創建新的Task

  明天再更新。。。。

 

 

 

 

 

 

 

 

 

 

 

 

 

二、小結

  • ActivityThread  

     ActivityThread類有一個main方法,它是應用程序的入口,每啟動一個應用進程,都會創建ActivityThread與之對應的實例,是應用程序的UI線程,Android進程啟動時會建立消息循環(前文圖解中也有說明)。

  • ApplicationThread & ApplicatinThreadNative

    ApplicationThread用來實現AMS(ActivityManagerService)與AT(ActivityThread)之間的交互。在AMS需要管理相關Application中的Activity的生命周期時,通過ApplicationThreadAT通訊,ApplicationThreadNativeApplicationThread在客戶端的實現(binder機制)。

  • ApplicationThreadProxy

    ApplicationThreadProxyApplicationThread在服務器端的代理。負責和服務器端的ApplicatingThreadNative通訊。 AMS就是通過該代理與ActivityThread進行通信的(binder機制)。

  • Activity & Intrumentation

    Activity是應用程序真正做事情的類,每一個應用程序只有一個Instrumentation對象,每個Activity內都有一個對該對象的引用(也就是說mInstrumentation是Activity類的成員變量,前文圖解中也有說明)。

    Instrumentation用來監控應用程序和系統的交互,可以理解為應用進程的管家,AT要創建或暫停某個Activity時,都需要通過Instrumentation。 通俗的理解,InstrumentationAT的區別,前者像是一個“家庭”里的“管家”,后者是負責創建這個“家庭”,並負責對外打交道,比如接收AMS的通知等。

 

后序

  本文在講訴的過程中查閱了大量的資料,其中講訴的一些知識難免會跟原作者“雷同”,望原作者諒解。剛接觸android,文中講訴的過程中難免會出現一些錯誤,希望大家能批評指正,另外后序的文章會不定時更新。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM