Android8.0(API26)之Activity启动流程(显示启动)
Posted 不一样的农民
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android8.0(API26)之Activity启动流程(显示启动)相关的知识,希望对你有一定的参考价值。
我们自己的启动Activity方法
调用Activity对象的方法
@Override public void startActivity(Intent intent) { this.startActivity(intent, null); }
继续调用Activity对象方法
@Override public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { // Note we want to go through this call for compatibility with // applications that may have overridden the method. startActivityForResult(intent, -1); } }
继续调用Activity对象方法
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) { startActivityForResult(intent, requestCode, null); }
继续调用Activity对象方法
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) {//mParent指的是ActivityGroup,可以在一个界面里嵌套多个Activity。随着版本的升级,在API13以后就废弃掉了。 options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(//调用了方法Instrumentation$execStartActivity,因为mParent为null。 this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult(//mMainThread是一个ActivityThread对象,该对象初始化在当前Activity的attach方法中。 mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } if (requestCode >= 0) { // If this start is requesting a result, we can avoid making // the activity visible until the result is received. Setting // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the // activity hidden during this time, to avoid flickering. // This can only be done when a result is requested because // that guarantees we will get information back when the // activity is finished, no matter what happens to it. mStartedActivity = true; } cancelInputsAndStartExitTransition(options); // TODO Consider clearing/flushing other event sources and events for child windows. } else { if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { // Note we want to go through this method for compatibility with // existing applications that may have overridden it. mParent.startActivityFromChild(this, intent, requestCode); } } }
在startActivityForResult这个方法中 我们发现如果
requestCode > 0会把标志位mStartedActivity改成true(这个关于)
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); }
这个方法是否回调。
在回头查看启动的重点:根据上面的注释我们继续查看Instrumentation的execStartActivity方法
1 public void execStartActivitiesAsUser(Context who, IBinder contextThread, 2 IBinder token, Activity target, Intent[] intents, Bundle options, 3 int userId) { 4 IApplicationThread whoThread = (IApplicationThread) contextThread;//ActivityThread的ApplictionThread对象 5 if (mActivityMonitors != null) { 6 synchronized (mSync) { 7 final int N = mActivityMonitors.size(); 8 for (int i=0; i<N; i++) { 9 final ActivityMonitor am = mActivityMonitors.get(i);//List<ActivityMonitor> mActivityMonitors 10 ActivityResult result = null; 11 if (am.ignoreMatchingSpecificIntents()) { 12 result = am.onStartActivity(intents[0]);//这个方法返回的是null 13 } 14 if (result != null) { 15 am.mHits++; 16 return; 17 } else if (am.match(who, null, intents[0])) {//用于拦截任何已启动的活动 18 am.mHits++; 19 if (am.isBlocking()) { 20 return; 21 } 22 break; 23 } 24 } 25 } 26 } 27 try { 28 String[] resolvedTypes = new String[intents.length]; 29 for (int i=0; i<intents.length; i++) { 30 intents[i].migrateExtraStreamToClipData(); 31 intents[i].prepareToLeaveProcess(who); 32 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver()); 33 } 34 int result = ActivityManager.getService() 35 .startActivities(whoThread, who.getBasePackageName(), intents, resolvedTypes, 36 token, options, userId); 37 checkStartActivityResult(result, intents[0]); 38 } catch (RemoteException e) { 39 throw new RuntimeException("Failure from system", e); 40 } 41 }
第4行代码:private class ApplicationThread extends IApplicationThread.Stub{}是在ActivityThread中ApplictionThread的构造方法、
通过代码分析(有注释)可知这里的重点事:
我们再来查看ActivityManager.getService()方法返回的对象:
1 public static IActivityManager getService() { 2 return IActivityManagerSingleton.get(); 3 } 4 5 private static final Singleton<IActivityManager> IActivityManagerSingleton = 6 new Singleton<IActivityManager>() { 7 @Override 8 protected IActivityManager create() { 9 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); 10 final IActivityManager am = IActivityManager.Stub.asInterface(b); 11 return am; 12 } 13 };
返回的对象是一个IActivityManager,其中Singleton<T>是创建一个T的单列对象通过get()方法获取T对象。所以这里获取的是一个IActivityManager对象
这里的大概意思就是基于(Bidler机制)获取ActivityManagerServer在应用进程的代理对象IActivityManager(这里需要了解Binder机制,会另外写bidler机制)
所以这里的Instrumentation中的getMananger.getServer.startActivity 等价于--IActivityManager.startActivity----等价于ActivityManagerServer.startActivity方法。
继续查看ActivityManagerServer对象的startActivity方法:
1 /** 2 * Instrumentaion 调用的是这个方法 3 * @return 返回值用于判断Activity是否启动 4 */ 5 @Override 6 public final int startActivity(IApplicationThread caller, String callingPackage, 7 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 8 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { 9 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 10 resultWho, requestCode, startFlags, profilerInfo, bOptions, 11 UserHandle.getCallingUserId()); 12 }
继续查看startActivityAsUer方法
@Override public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { enforceNotIsolatedCaller("startActivity"); //获取userid userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null); // TODO: 在这里切换到用户应用程序栈。(Switch to user app stacks here.) return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, bOptions, false, userId, null, null, "startActivityAsUser"); }
继续查看mActivityStarter.startActivityMayWait方法,mActivityStarter是ActivityStarter对象
1 final int startActivityMayWait(IApplicationThread caller, int callingUid, 2 String callingPackage, Intent intent, String resolvedType, 3 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 4 IBinder resultTo, String resultWho, int requestCode, int startFlags, 5 ProfilerInfo profilerInfo, WaitResult outResult, 6 Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId, 7 IActivityContainer iContainer, TaskRecord inTask, String reason) { 8 // Refuse possible leaked file descriptors 9 if (intent != null && intent.hasFileDescriptors()) { 10 throw new IllegalArgumentException("File descriptors passed in Intent"); 11 } 12 //调用底层的方法 给ActivityMetricsLogger的INVALID_START_TIME赋值 13 mSupervisor.mActivityMetricsLogger.notifyActivityLaunching(); 14 boolean componentSpecified = intent.getComponent() != null;//显示启动为true 15 16 // Save a copy in case ephemeral needs it 17 final Intent ephemeralIntent = new Intent(intent); 18 // Don\'t modify the client\'s object! 19 //为了不改变用户的intent 20 intent = new Intent(intent); 21 if (componentSpecified 22 && intent.getData() != null 23 && Intent.ACTION_VIEW.equals(intent.getAction()) 24 && mService.getPackageManagerInternalLocked() 25 .isInstantAppInstallerComponent(intent.getComponent())) {//判断是否调用系统功能 26 // intercept intents targeted directly to the ephemeral installer the 27 // ephemeral installer should never be started with a raw URL; instead 28 // adjust the intent so it looks like a "normal" instant app launch 29 intent.setComponent(null /*component*/); 30 componentSpecified = false; 31 } 32 //收集Intent所指向的Activity信息, 当存在多个可供选择的Activity,则直接向用户弹出resolveActivity 33 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId); 34 if (rInfo == null) { 35 UserInfo userInfo = mSupervisor.getUserInfo(userId);//UserInfo 保存了应用相关信息 名字 图片.... 36 if (userInfo != null && userInfo.isManagedProfile()) {//不会执行(估计) 37 // Special case for managed profiles, if attempting to launch non-cryto aware 38 // app in a locked managed profile from an unlocked parent allow it to resolve 39 // as user will be sent via confirm credentials to unlock the profile. 40 UserManager userManager = UserManager.get(mService.mContext); 41 boolean profileLockedAndParentUnlockingOrUnlocked = false; 42 long token = Binder.clearCallingIdentity(); 43 try { 44 UserInfo parent = userManager.getProfileParent(userId); 45 profileLockedAndParentUnlockingOrUnlocked = (parent != null) 46 && userManager.isUserUnlockingOrUnlocked(parent.id) 47 && !userManager.isUserUnlockingOrUnlocked(userId); 48 } finally { 49 Binder.restoreCallingIdentity(token); 50 } 51 if (profileLockedAndParentUnlockingOrUnlocked) { 52 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 53 PackageManager.MATCH_DIRECT_BOOT_AWARE 54 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 55 } 56 } 57 } 58 // 收集有关目标的信息。(Collect information about the target of the Intent.) 59 //收集目标intent的信息,在resolveActivity方法中与PKMS交互获得 60 //该过程主要功能:通过resolveActivity来获取ActivityInfo信息, 找到相应的Activity组件,并保存到intent对象,然后再进入startActivityLocked() 61 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); 62 63 ActivityOptions options = ActivityOptions.fromBundle(bOptions); 64 ActivityStackSupervisor.ActivityContainer container = 65 (ActivityStackSupervisor.ActivityContainer)iContainer; 66 synchronized (mService) { 67 if (container != null && container.mParentActivity != null && 68 container.mParentActivity.state != RESUMED) { 69 // Cannot start a child activity if the parent is not resumed. 70 return ActivityManager.START_CANCELED; 71 } 72 final int realCallingPid = Binder.getCallingPid(); 73 final int realCallingUid = Binder.getCallingUid(); 74 int callingPid; 75 if (callingUid >= 0) { 76 callingPid = -1; 77 } else if (caller == null) { 78 callingPid = realCallingPid; 79 callingUid = realCallingUid; 80 } else { 81 callingPid = callingUid = -1; 82 } 83 84 final ActivityStack stack; 85 //取得需要启动的ActivityStack栈 86 if (container == null || container.mStack.isOnHomeDisplay()) { 87 stack = mSupervisor.mFocusedStack; 88 } else { 89 stack = container.mStack; 90 } 91 stack.mConfigWillChange = globalConfig != null 92 && mService.getGlobalConfiguration().diff(globalConfig) != 0; 93 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 94 "Starting activity when config will change = " + stack.mConfigWillChange); 95 96 final long origId = Binder.clearCallingIdentity(); 97 98 if (aInfo != null && 99 (aInfo.applicationInfo.privateFlags 100 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { 101 // This may be a heavy-weight process! Check to see if we already 102 // have another, different heavy-weight process running. 103 //androidmanifest.xml中的Application标签可以声明一个cantSaveState属性,若设置,其将不享受系统提 104 //供的状态保存/恢复功能。主要是为了保证用户体验的连续性 105 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { 106 final ProcessRecord heavy = mService.mHeavyWeightProcess; 107 if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid 108 || !heavy.processName.equals(aInfo.processName))) { 109 int appCallingUid = callingUid; 110 if (caller != null) { 111 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 112 if (callerApp != null) { 113 appCallingUid = callerApp.info.uid; 114 } else { 115 Slog.w(TAG, "Unable to find app for caller " + caller 116 + " (pid=" + callingPid + ") when starting: " 117 + intent.toString()); 118 ActivityOptions.abort(options); 119 return ActivityManager.START_PERMISSION_DENIED; 120 } 121 } 122 123 IIntentSender target = mService.getIntentSenderLocked( 124 ActivityManager.INTENT_SENDER_ACTIVITY, "android", 125 appCallingUid, userId, null, null, 0, new Intent[] { intent }, 126 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT 127 | PendingIntent.FLAG_ONE_SHOT, null); 128 129 Intent newIntent = new Intent(); 130 if (requestCode >= 0) { 131 // Caller is requesting a result. 132 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 133 } 134 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, 135 new IntentSender(target)); 136 if (heavy.activities.size() > 0) { 137 ActivityRecord hist = heavy.activities.get(0); 138 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, 139 hist.packageName); 140 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, 141 hist.getTask().taskId); 142 } 143 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 144 aInfo.packageName); 145 newIntent.setFlags(intent.getFlags()); 146 newIntent.setClassName("android", 147 HeavyWeightSwitcherActivity.class.getName()); 148 intent = newIntent; 149 resolvedType = null; 150 caller = null; 151 callingUid = Binder.getCallingUid(); 152 callingPid = Binder.getCallingPid(); 153 componentSpecified = true; 154 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId); 155 aInfo = rInfo != null ? rInfo.activityInfo : null; 156 if (aInfo != null) { 157 aInfo = mService.getActivityInfoForUser(aInfo, userId); 158 } 159 } 160 } 161 } 162 final ActivityRecord[] outRecord = new ActivityRecord[1]; 163 //启动Activity 164 int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, 165 aInfo, rInfo, voiceSession, voiceInteractor, 166 resultTo, resultWho, requestCode, callingPid, 167 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, 168 options, ignoreTargetSecurity, componentSpecified, outRecord, container, 169 inTask, reason); 170 171 Binder.restoreCallingIdentity(origId); 172 //如果配置Configration发生变化,则调用AMS的updateConfigurationLocked进行处理 173 if (stack.mConfigWillChange) { 174 // If the caller also wants to switch to a new configuration, 175 // do so now. This allows a clean switch, as we are waiting 176 // for the current activity to pause (so we will not destroy 177 // it), and have not yet started the next activity. 178 //如果调用方也希望切换到新配置 179 //现在就这样做。这允许一个干净的开关,因为我们正在等待 180 //为当前活动暂停(因此我们不会破坏) 181 //它还没有启动下一个活动。 182 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 183 "updateConfiguration()"); 184 stack.mConfigWillChange = false; 185 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 186 "Updating to new configuration after starting activity."); 187 mService.updateConfigurationLocked(globalConfig, null, false); 188 } 189 190 if (outResult != null) { 191 outResult.result = res; 192 if (res == ActivityManager.START_SUCCESS) { 193 //将结果放入mWaitingActivityLaunced中保存 194 mSupervisor.mWaitingActivityLaunched.add(outResult); 195 do { 196 try { 197 //等待启动结果 198 mService.wait(); 199 } catch (InterruptedException e) { 200 } 201 } while (outResult.result != START_TASK_TO_FRONT 202 && !outResult.timeout && outResult.who == null); 203 if (outResult.result == START_TASK_TO_FRONT) { 204 res = START_TASK_TO_FRONT; 205 } 206 } 207 if (res == START_TASK_TO_FRONT) { 208 final ActivityRecord r = outRecord[0]; 209 210 // ActivityRecord may represent a different activity, but it should not be in 211 // the resumed state. 212 if (r.nowVisible && r.state == RESUMED) { 213 outResult.timeout = false; 214 outResult.who = r.realActivity; 215 outResult.totalTime = 0; 216 outResult.thisTime = 0; 217 } else { 218 outResult.thisTime = SystemClock.uptimeMillis(); 219 mSupervisor.waitActivityVisible(r.realActivity, outResult); 220 // Note: the timeout variable is not currently not ever set. 221以上是关于Android8.0(API26)之Activity启动流程(显示启动)的主要内容,如果未能解决你的问题,请参考以下文章