前言
- 基於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的生命周期時,通過ApplicationThread與AT通訊,ApplicationThreadNative是ApplicationThread在客戶端的實現(binder機制)。
- ApplicationThreadProxy
ApplicationThreadProxy是ApplicationThread在服務器端的代理。負責和服務器端的ApplicatingThreadNative通訊。 AMS就是通過該代理與ActivityThread進行通信的(binder機制)。
- Activity & Intrumentation
Activity是應用程序真正做事情的類,每一個應用程序只有一個Instrumentation對象,每個Activity內都有一個對該對象的引用(也就是說mInstrumentation是Activity類的成員變量,前文圖解中也有說明)。
Instrumentation用來監控應用程序和系統的交互,可以理解為應用進程的管家,AT要創建或暫停某個Activity時,都需要通過Instrumentation。 通俗的理解,Instrumentation與AT的區別,前者像是一個“家庭”里的“管家”,后者是負責創建這個“家庭”,並負責對外打交道,比如接收AMS的通知等。
后序
本文在講訴的過程中查閱了大量的資料,其中講訴的一些知識難免會跟原作者“雷同”,望原作者諒解。剛接觸android,文中講訴的過程中難免會出現一些錯誤,希望大家能批評指正,另外后序的文章會不定時更新。