图解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的生命周期时,通过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,文中讲诉的过程中难免会出现一些错误,希望大家能批评指正,另外后序的文章会不定时更新。