当前位置: 首页 > news >正文

网站建设情况的自查报告兵团建设环保局门户网站

网站建设情况的自查报告,兵团建设环保局门户网站,包装网站开发,wordpress快速登陆插件前言 在Android开发中#xff0c;我们经常会用到startActivity(Intent)方法#xff0c;但是你知道startActivity(Intent)后Activity的启动流程吗#xff1f;今天就专门讲一下最基础的startActivity(Intent)看一下Activity的启动流程#xff0c;同时由于Launcher的启动后续…前言 在Android开发中我们经常会用到startActivity(Intent)方法但是你知道startActivity(Intent)后Activity的启动流程吗今天就专门讲一下最基础的startActivity(Intent)看一下Activity的启动流程同时由于Launcher的启动后续和这里基本类似就记录在一起。注意本章都是基于Android-10来讲解的。 客户端startActivity启动流程 startActivity启动流程本质上就是向ActivityManagerService发送启动请求。由于发送端基本是在当前用户App进程或者Launcher进程从桌面启动新的App。除了SystemServer启动Launcher外都需要借助AIDL发送请求。 1:客户端启动流程 startActivity方法在ActivitystartActivity有两个重载方法最终都会调用startActivityForResult(Intent,int, Bundle)方法代码如下 public void startActivityForResult(RequiresPermission Intent intent, int requestCode,Nullable Bundle options) {if (mParent null) {//...Instrumentation.ActivityResult ar mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);//...} else {if (options ! null) {mParent.startActivityFromChild(this, intent, requestCode, options);} else {mParent.startActivityFromChild(this, intent, requestCode);}} }其中mParent是当前Activity的父Activity目前我只能想到TabActivity场景下才会存在一个Activity中包含Activity的情况虽然它已经被Fragment替代了。所以基本上代码都是走mParent null的流程调用Instrumentation的execStartActivity方法。当然在startActivityFromChild 方法里也是如此不难发现该方法已经被废弃了,源码如下俩个重载的方法均已经废弃 /** deprecated */Deprecatedpublic void startActivityFromChild(NonNull Activity child, Intent intent, int requestCode) {throw new RuntimeException(Stub!);}/** deprecated */Deprecatedpublic void startActivityFromChild(NonNull Activity child, Intent intent, int requestCode, Nullable Bundle options) {throw new RuntimeException(Stub!);}我们继续看execStartActivity方法的关键代码 public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {//...try {intent.migrateExtraStreamToClipData(who);intent.prepareToLeaveProcess(who);//备注一int result ActivityTaskManager.getService().startActivity(whoThread,who.getBasePackageName(), who.getAttributionTag(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()), token,target ! null ? target.mEmbeddedID : null, requestCode, 0, null, options);//备注二checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException(Failure from system, e);}return null; }其中备注一处就是获取ActivityTaskManager服务并向其发送请求。备注二处会根据备注一处的返回结果检查Activity的启动状态源码如下 public static void checkStartActivityResult(int res, Object intent) {if (!ActivityManager.isStartResultFatalError(res)) {//如果没法发生启动错误直接返回return;}switch (res) {case ActivityManager.START_INTENT_NOT_RESOLVED:case ActivityManager.START_CLASS_NOT_FOUND:if (intent instanceof Intent ((Intent)intent).getComponent() ! null)throw new ActivityNotFoundException(Unable to find explicit activity class ((Intent)intent).getComponent().toShortString() ; have you declared this activity in your AndroidManifest.xml?);throw new ActivityNotFoundException(No Activity found to handle intent);case ActivityManager.START_PERMISSION_DENIED:throw new SecurityException(Not allowed to start activity intent);case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:throw new AndroidRuntimeException(FORWARD_RESULT_FLAG used while also requesting a result);//...default:throw new AndroidRuntimeException(Unknown error code res when starting intent);} }可以看到checkStartActivityResult在Activity里会根据启动失败的原因并抛出异常注意里面的case ActivityManager.START_CLASS_NOT_FOUND你一定知道如果没有在AndroidManifest.xml文件里声明Activity就会抛出异常。没错就是根据AMS返回的错误码在这里抛出的异常。 当然检查并不是在这里。checkStartActivityResult不负责任何启动Activity以及检查配置文件的工作它之负责根据AMS的返回结果抛出异常。接下来回到备注一看一下重点工作 ActivityTaskManager的getService方法。 public static IActivityTaskManager getService() {return IActivityTaskManagerSingleton.get();}UnsupportedAppUsage(trackingBug 129726065) private static final SingletonIActivityTaskManager IActivityTaskManagerSingleton new SingletonIActivityTaskManager() {Overrideprotected IActivityTaskManager create() {final IBinder b ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);return IActivityTaskManager.Stub.asInterface(b);}};代码比较简单一个匿名内部类IActivityTaskManagerSingleton里面的create 方法返回了一个IActivityTaskManager对象根据方法里的内容就能猜出它个AIDL该AIDL文件可在IActivityTaskManager源码里查看。 接着看一个ActivityTaskManagerSingleton.get()方法get方法在它的父类Singleton中定义 public abstract class SingletonT {UnsupportedAppUsagepublic Singleton() {}UnsupportedAppUsageprivate T mInstance;protected abstract T create();UnsupportedAppUsagepublic final T get() {synchronized (this) {if (mInstance null) {mInstance create();}return mInstance;}} }很简单的代码一个懒汉式单例。如果实例为空就调用create()方法也就是上文中匿名内部类中复写的方法。到这里一切就明了了这里就准备开始跨进程通讯了ActivityTaskManager.getService方法就是客户端发起创建Activity的当前App进程向服务端AMS获取获取Binder对象用于跨进程通讯。而关键代码就是IActivityTaskManager.Stub.asInterface(b)。注意IActivityTaskManager只是个AIDL文件是为了自动生成代码的工具更多关于AIDL的知识请看Android里的多进程和跨进程通讯方式) 接下来看final IBinder b ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);看它是如何获得Binder实例的 private static MapString, IBinder sCache new ArrayMapString, IBinder();public static IBinder getService(String name) {try {IBinder service sCache.get(name);if (service ! null) {// 有缓存直接从缓存获取return service;} else {// 没有缓存重新通过ServiceManager获取return Binder.allowBlocking(rawGetService(name));}} catch (RemoteException e) {Log.e(TAG, error in getService, e);}return null; }上面是ServiceManager.getService方法的代码。ServiceManager是Android用来关系系统服务的Android系统给我们提供了很多服务每一个服务都有一个对应的类AMS,WMS等开发过程中我们就是通过这些类来获得我们所需要的服务。而ServiceManager则通过一个ArrayMap来缓存这些服务。这里也是如此getService(Context.ACTIVITY_TASK_SERVICE)不难看出是要获得ActivityTaskManagerService的。看一下ActivityTaskManagerService 它继承了IActivityTaskManager.Stub就和上文中我们的AIDL文件对应上了。可以肯定ActivityTaskManagerService就是这次AIDL跨进程通讯的服务端了。 为了以防万一我们还是要追踪一下ActivityTaskManagerService是如何添加到ServiceManager中的。这时我们就要了解一下Android系统的启动流程了ActivityTaskManagerService作为系统服务是在SystemServer中被启动的 ActivityTaskManagerService atm mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerService ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm); 其中SystemServiceManager.startService是通过反射创建Service的: public T extends SystemService T startService(ClassT serviceClass) {try {final String name serviceClass.getName();//..final T service;try {//通过反射创建实例ConstructorT constructor serviceClass.getConstructor(Context.class);service constructor.newInstance(mContext);} catch (InstantiationException ex) {throw new RuntimeException(Failed to create service name : service could not be instantiated, ex);} //...//启动服务startService(service);return service;} finally {Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);} } 代码很简单就是通过反射创建服务并启动。我们接着看启动服务的startService(service);方法: public void startService(NonNull final SystemService service) {//..try {service.onStart();} catch (RuntimeException ex) {throw new RuntimeException(Failed to start service service.getClass().getName() : onStart threw an exception, ex);}} 这里可以看出明明我们创建的是ActivityTaskManagerServiceLifecycle但是上面这段代码却是接收一个SystemService并调用它的onStart方法原因只有一个ActivityTaskManagerServiceLifecycle是SystemService的子类 public static final class Lifecycle extends SystemService {private final ActivityTaskManagerService mService;public Lifecycle(Context context) {super(context);mService new ActivityTaskManagerService(context);}Overridepublic void onStart() {publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);mService.start();}//... } 看一下源码也确实如此那么紧接着看SystemService在Lifecycle中的实现中的一行代码publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);。这里有出现了Context.ACTIVITY_TASK_SERVICE。就是在这里将ActivityTaskManagerService添加到ServiceManager中的。查看源码可发现SystemService有多个publishBinderService重载并最终都调用了 protected final void publishBinderService(String name, IBinder service,boolean allowIsolated, int dumpPriority) {ServiceManager.addService(name, service, allowIsolated, dumpPriority);} 没错这里就调用了ServiceManager.addService方法了。最终调用方法在ServiceManager中 public static void addService(String name, IBinder service, boolean allowIsolated,int dumpPriority) {try {getIServiceManager().addService(name, service, allowIsolated, dumpPriority);} catch (RemoteException e) {Log.e(TAG, error in addService, e);} }private static IServiceManager getIServiceManager() {if (sServiceManager ! null) {return sServiceManager;}// Find the service managersServiceManager ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));return sServiceManager; } 至此服务的获取也明确了ActivityTaskManagerService就是在系统启动时创建的。 2:服务端接收请求流程 接下来就是继续看startActivity方法了客户端Instrumentation调用服务端ActivityTaskManagerService响应。ActivityTaskManagerService中有多个startActivity重载方法。经过不断调用最终会调用startActivityAsUser方法 int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,boolean validateIncomingUser) {enforceNotIsolatedCaller(startActivityAsUser);userId getActivityStartController().checkTargetUser(userId, validateIncomingUser,Binder.getCallingPid(), Binder.getCallingUid(), startActivityAsUser);return getActivityStartController().obtainStarter(intent, startActivityAsUser).setCaller(caller).setCallingPackage(callingPackage).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setProfilerInfo(profilerInfo).setActivityOptions(bOptions).setMayWait(userId).execute(); //启动} 注意看ActivityStartController. obtainStarter方法其中最后的execute最终是执行的ActivityStarter的execute代码: /*** Starts an activity based on the request parameters provided earlier.* return The starter result.*/int execute() {try {// TODO(b/64750076): Look into passing request directly to these methods to allow// for transactional diffs and preprocessing.if (mRequest.mayWait) {return startActivityMayWait(mRequest.caller, mRequest.callingUid,mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,mRequest.intent, mRequest.resolvedType,mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,mRequest.inTask, mRequest.reason,mRequest.allowPendingRemoteAnimationRegistryLookup,mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);} else {return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,mRequest.ignoreTargetSecurity, mRequest.componentSpecified,mRequest.outActivity, mRequest.inTask, mRequest.reason,mRequest.allowPendingRemoteAnimationRegistryLookup,mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);}} finally {onExecutionComplete();}} 其中startActivity有三个的重载方法经过不断的调用最后会调用startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity, boolean restrictedBgActivity) 方法 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity, boolean restrictedBgActivity) {try {mService.mWindowManager.deferSurfaceLayout();result startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);} } 大致的流程图如下 但是到了Launcher启动Activity时变终止了最终在这里合流。 public class ActivityStartController {.... ActivityStarter obtainStarter(Intent intent, String reason) {return mFactory.obtain().setIntent(intent).setReason(reason);} } 所以整个客户端的请求和处理流程大致如下 接下来就要开始创建了。 服务端处理流程 我们一步步分析看服务端的处理流程。 1:检验、初始化等基础工作 ActivityStarter有多个startActivity的重载方法。最终执行的关键代码如下 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,String callingPackage, int realCallingPid, int realCallingUid, int startFlags,SafeActivityOptions options,boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {//...//创建错误码默认是成功的int err ActivityManager.START_SUCCESS;// Pull the optional Ephemeral Installer-only bundle out of the options early.final Bundle verificationBundle options ! null ? options.popAppVerificationBundle() : null;//..final int userId aInfo ! null aInfo.applicationInfo ! null? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;//.. final int launchFlags intent.getFlags();//..//开始处理错误//找不到可以处理给定Intent的类if (err ActivityManager.START_SUCCESS intent.getComponent() null) {err ActivityManager.START_INTENT_NOT_RESOLVED;}//找不到Intent中指定的Ativity类就是对应我们上文中没有在配置文件里配置Activityif (err ActivityManager.START_SUCCESS aInfo null) {err ActivityManager.START_CLASS_NOT_FOUND;}//..final ActivityStack resultStack resultRecord null? null : resultRecord.getActivityStack();//如果错误码被改变不为成功则返回给客户端启动失败 if (err ! START_SUCCESS) {if (resultRecord ! null) {resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);}SafeActivityOptions.abort(options);return err;}// 检查启动activity的权限boolean abort !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,inTask ! null, callerApp, resultRecord, resultStack);abort | !mService.mIntentFirewall.checkStartActivity(intent, callingUid,callingPid, resolvedType, aInfo.applicationInfo);abort | !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,callingPackage);// 检查是否允许后台启动activityif (!abort) {try {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,shouldAbortBackgroundActivityStart);restrictedBgActivity shouldAbortBackgroundActivityStart(callingUid,callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,originatingPendingIntent, allowBackgroundActivityStart, intent);} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}//..// 判断如果有权限需要哦用户审阅才能运行Activityif (aInfo ! null) {// 获取此包使用的某些权限是否需要用户审核才能运行任何应用程序组件if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(aInfo.packageName, userId)) {IIntentSender target mService.getIntentSenderLocked(ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,callingUid, userId, null, null, 0, new Intent[]{intent},new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT| PendingIntent.FLAG_ONE_SHOT, null);Intent newIntent new Intent(Intent.ACTION_REVIEW_PERMISSIONS);//..}}//创建ActivityRecordActivityRecord r new ActivityRecord(mService, callerApp, callingPid, callingUid,callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),resultRecord, resultWho, requestCode, componentSpecified, voiceSession ! null,mSupervisor, checkedOptions, sourceRecord);//..//创建ActivityStackfinal ActivityStack stack mRootActivityContainer.getTopDisplayFocusedStack();//..// 进入启动activity的流程final int res startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);return res;} 该方法主要做了一下两件事 执行初步的配置、权限等基本的检查工作创建ActivityRecord对象并获取ActivityStack对象。 第一步的检查包括Intent的检查包括里面Activity的类型检查。还要进行权限是否允许后台启动等检查。第二部主要是创建Activity启动的辅助类ActivityRecord负责存储一些关于Activity组件的相关信息。是应用层Activity组件在AMS中的代表每一个在应用中启动的Activity在AMS中都有一个ActivityRecord实例来与之对应。ActivityRecord则由TaskRecord通过一个ArrayList管理而ActivityStack则用来管理TaskRecord。它们之间的关系大致如下图片所示 紧接着又会调用startActivity的重载方法 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity, boolean restrictedBgActivity) {int result START_CANCELED;final ActivityStack startedActivityStack;try {//准备启动暂停页面布局绘制mService.mWindowManager.deferSurfaceLayout();result startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);} finally {final ActivityStack currentStack r.getActivityStack();startedActivityStack currentStack ! null ? currentStack : mTargetStack;if (ActivityManager.isStartResultSuccessful(result)) {if (startedActivityStack ! null) {//处理Activity信息并确保显示更新方向等配置信息final ActivityRecord currentTop startedActivityStack.topRunningActivityLocked();if (currentTop ! null currentTop.shouldUpdateConfigForDisplayChanged()) {mRootActivityContainer.ensureVisibilityAndConfig(currentTop, currentTop.getDisplayId(),true /* markFrozenIfConfigChanged */, false /* deferResume */);}}} else {//如果失败了请取消Activity与栈的关联。//让Activity处于不完整状态可能会导致问题//例如在没有窗口容器的情况下执行操作。final ActivityStack stack mStartActivity.getActivityStack();if (stack ! null) {stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,null /* intentResultData */, startActivity, true /* oomAdj */);}//执行失败的逻辑移除堆信息if (startedActivityStack ! null startedActivityStack.isAttached() startedActivityStack.numActivities() 0 !startedActivityStack.isActivityTypeHome()) {startedActivityStack.remove();}}//重新开始绘制mService.mWindowManager.continueSurfaceLayout();}postStartActivityProcessing(r, result, startedActivityStack);return result;} 代码的详细解读写在了注释里面。这里关键的步骤就是调用startActivityUnchecked。 2:任务栈的创建和获取 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity, boolean restrictedBgActivity) {//初始化Activity配置 //此处会直接将mDoResume设置为true//在该方法末尾会用到setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,voiceInteractor, restrictedBgActivity);final int preferredWindowingMode mLaunchParams.mWindowingMode;//计算Activity的Flag也就是mLaunchFlagscomputeLaunchingTaskFlags();computeSourceStack();//将mLaunchFlags设置给mIntentmIntent.setFlags(mLaunchFlags);//判断Activity是否可以放入到一个已经存在的任务栈//如果返回null则标识需要新的任务栈ActivityRecord reusedActivity getReusableIntentActivity();//..//如果有可以复用的ActivityRecordif (reusedActivity ! null) {//..//判断是否需要清空任务栈栈顶final boolean clearTopAndResetStandardLaunchMode (mLaunchFlags (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)) (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) mLaunchMode LAUNCH_MULTIPLE;//将ActivityRecord加入到TaskRecordif (mStartActivity.getTaskRecord() null !clearTopAndResetStandardLaunchMode) {mStartActivity.setTask(reusedActivity.getTaskRecord());}// 判断是否要清除TaskRecordif ((mLaunchFlags FLAG_ACTIVITY_CLEAR_TOP) ! 0|| isDocumentLaunchesIntoExisting(mLaunchFlags)|| isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {//获取可复用的TaskRecordfinal TaskRecord task reusedActivity.getTaskRecord();final ActivityRecord top task.performClearTaskForReuseLocked(mStartActivity,mLaunchFlags);//重新进行赋值if (reusedActivity.getTaskRecord() null) {reusedActivity.setTask(task);}//..}mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);//将被复用的Task防置到前台reusedActivity setTargetStackAndMoveToFrontIfNeeded(reusedActivity);final ActivityRecord outResult outActivity ! null outActivity.length 0 ? outActivity[0] : null;// When there is a reused activity and the current result is a trampoline activity,// set the reused activity as the result.if (outResult ! null (outResult.finishing || outResult.noDisplay)) {outActivity[0] reusedActivity;}if ((mStartFlags START_FLAG_ONLY_IF_NEEDED) ! 0) {//START_FLAG_ONLY_IF_NEEDED:只需要使task放到前台,无需去启动(eg. 从桌面点击图标恢复task的情况)。resumeTargetStackIfNeeded();return START_RETURN_INTENT_TO_CALLER;}if (reusedActivity ! null) {setTaskFromIntentActivity(reusedActivity);if (!mAddingToTask mReuseTask null) {//将Stack调用到前台resumeTargetStackIfNeeded();//..return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;}}}// ..// 接下来判断要启动的Activity和当前栈顶的是否一样//并且判断时序需要启动final ActivityStack topStack mRootActivityContainer.getTopDisplayFocusedStack();final ActivityRecord topFocused topStack.getTopActivity();final ActivityRecord top topStack.topRunningNonDelayedActivityLocked(mNotTop);//判断是否需要启动Activityfinal boolean dontStart top ! null mStartActivity.resultTo null top.mActivityComponent.equals(mStartActivity.mActivityComponent) top.mUserId mStartActivity.mUserId top.attachedToProcess() ((mLaunchFlags FLAG_ACTIVITY_SINGLE_TOP) ! 0|| isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) (!top.isActivityTypeHome() || top.getDisplayId() mPreferredDisplayId);if (dontStart) {//无需重启直接将当前activity显示到前台topStack.mLastPausedActivity null;if (mDoResume) {mRootActivityContainer.resumeFocusedStacksTopActivities();}//..//返回启动结果结束return START_DELIVERED_TO_TOP;}boolean newTask false;final TaskRecord taskToAffiliate (mLaunchTaskBehind mSourceRecord ! null)? mSourceRecord.getTaskRecord() : null;int result START_SUCCESS;// 判断是否需要一个新的任务栈// 并分情况设置任务栈if (mStartActivity.resultTo null mInTask null !mAddingToTask (mLaunchFlags FLAG_ACTIVITY_NEW_TASK) ! 0) {newTask true;result setTaskFromReuseOrCreateNewTask(taskToAffiliate);} else if (mSourceRecord ! null) {result setTaskFromSourceRecord();} else if (mInTask ! null) {result setTaskFromInTask();} else {result setTaskToCurrentTopOrCreateNewTask();}//根据设置任务栈的返回值判断是否发生错误//如果发生了错误那么就直接返回if (result ! START_SUCCESS) {return result;}//..//这里我们只关注mDoResume为true的情况//因为在我们上文中startActivity方法中有如下调用//final int res startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,// true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);//其中的doResume在该方法开头第一步就会将mDoResume设置为trueif (mDoResume) {final ActivityRecord topTaskActivity mStartActivity.getTaskRecord().topRunningActivityLocked();//如果当前任务栈没有获得焦点走这里//我们按照主流程会走else if (!mTargetStack.isFocusable()|| (topTaskActivity ! null topTaskActivity.mTaskOverlay mStartActivity ! topTaskActivity)) {//..} else {if (mTargetStack.isFocusable() !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {mTargetStack.moveToFront(startActivityUnchecked);}mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);}} else if (mStartActivity ! null) {//..}//..return START_SUCCESS;} 该方法代码量很大关键的节点已经写在注释里面了。但是它的工作其实也很简单主要就是准备好任务栈并且将acticityRecord加入到TaskRecord中。而它的复杂支出就在于复用等一系列的判断和准备工作。 这里补充一下getReusableIntentActivity判断任务栈复用的关键代码 private ActivityRecord getReusableIntentActivity() {//android会尽量的将Activity放入到已经存在的任务栈中//尤其是使用了singleTask和singleInstance模式启动的Activity//而对于使用了FLAG_ACTIVITY_NEW_TASK也会尽量保持这种风格//以下集中情况才会允许插入到已经存在的任务栈里//standard启动模式而且intent且添加FLAG_ACTIVITY_NEW_TASK//使用singleTask和singleInstance启动的Activityboolean putIntoExistingTask ((mLaunchFlags FLAG_ACTIVITY_NEW_TASK) ! 0 (mLaunchFlags FLAG_ACTIVITY_MULTIPLE_TASK) 0)|| isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);ActivityRecord intentActivity null;if (mOptions ! null mOptions.getLaunchTaskId() ! -1) {final TaskRecord task mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());intentActivity task ! null ? task.getTopActivity() : null;} else if (putIntoExistingTask) {//..//省略复用的逻辑}//不能复用桌面Activityif (intentActivity ! null (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome()) intentActivity.getDisplayId() ! mPreferredDisplayId) {intentActivity null;}return intentActivity;} 此时任务栈已经准备好了。紧接着关注一下 mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);也就是RootActivityContainer.resumeFocusedStacksTopActivities方法 boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {//..boolean result false;if (targetStack ! null (targetStack.isTopStackOnDisplay()|| getTopDisplayFocusedStack() targetStack)) {//如果Activity的目标栈正处于前台那么直接调用方法//将ActivityRecordtarget放置到顶部result targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}for (int displayNdx mActivityDisplays.size() - 1; displayNdx 0; --displayNdx) {boolean resumedOnDisplay false;final ActivityDisplay display mActivityDisplays.get(displayNdx);//..//如果目标栈没有显示在屏幕上//则获取当前的ActivityStack将ActivityRecordtarget放置到顶部if (!resumedOnDisplay) {final ActivityStack focusedStack display.getFocusedStack();if (focusedStack ! null) {focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);}}}return result;} 该段代码的目的就是为了让目标的Activity的表述ActivityRecordtarget放置在前台。当然是通过ActivityStack.resumeTopActivityUncheckedLocked方法实现的。注意此时放置我们要启动Activity的ActivityRecord的TaskRecord已经放在了前台同时该ActivityRecord处在顶部。 3:通知ActivityThread创建 接下来关注关键的步骤调用了resumeTopActivityInnerLocked方法 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {if (!mService.isBooting() !mService.isBooted()) {// Not ready yet!return false;}//找到当前Task里最顶层的ActivityRecord//注意不是Activity的任务栈而是ActivityTask//可以理解为是启动我们Activity(B)的Activity(A)//A可能是不同App的比如Launcher也可能是和B同一应用内//还记得上段代码的任务吗放置我们要启动Activity的ActivityRecord的TaskRecord已经放在了前台//同时该ActivityRecord处在顶部。//这个next就是我们要启动的了ActivityRecord next topRunningActivityLocked(true /* focusableOnly */);//..//判断是否还有其他RESUMED状态的Activityif (mResumedActivity next next.isState(RESUMED) display.allResumedActivitiesComplete()) {// Make sure we have executed any pending transitions, since there// should be nothing left to do at this point.executeAppTransition(options);if (DEBUG_STATES) Slog.d(TAG_STATES,resumeTopActivityLocked: Top activity resumed next);return false;}//..//重点一//调用ActivityDisplay.pauseBackStacks方法暂停后台Stack的Activityboolean pausing getDisplay().pauseBackStacks(userLeaving, next, false);//暂停掉当前Stacks里处于活动状态的Activityif (mResumedActivity ! null) {if (DEBUG_STATES) Slog.d(TAG_STATES,resumeTopActivityLocked: Pausing mResumedActivity);pausing | startPausingLocked(userLeaving, false, next, false);}//判断要启动的Activity所要运行的进程是否已经存在if (next.attachedToProcess()) {try {//重点二//当Activity之前启动过直接resumefinal ClientTransaction transaction ClientTransaction.obtain(next.app.getThread(), next.appToken);//..mService.getLifecycleManager().scheduleTransaction(transaction);if (DEBUG_STATES) Slog.d(TAG_STATES, resumeTopActivityLocked: Resumed next);} catch (Exception e) {// Whoops, need to restart this activity!//..//重点三mStackSupervisor.startSpecificActivityLocked(next, true, false);}//.. } else {//进程没有运行走启动进程的流程//..//重点四//创建进程的的逻辑就不展开了创建完成之后之后最终还是会走后续的流程mStackSupervisor.startSpecificActivityLocked(next, true, true);}return true;} 代码注释比较详细了这里解读一下关键点 重点一暂停掉处在前台的Activity该步骤最终是通过startPausingLocked方法实现的在这里调用了当前正在显示的Activity的onPause方法。重点二如果之前Activity启动过直接resume否则的话抛出异常进入重点三重点三向ActivityThread发送创建Activity的请求。重点四如果Activity所要运行的线程还未创建那么就会请求Zygote创建进程创建过程就不展开说了。而在进程创建完之后。Zygote会通过Binder通知ATMSActivityTaskManagerService紧接着又会通过类似重点二的方式请求ActivityThread创建。 接着我们看看是如何通知ActivityThread创建Activity的。分析重点三处的代码它会通过ActivityStackSupervisor.startSpecificActivityLocked调用ActivityStackSupervisor.realStartActivityLocked方法 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {//..try {//..// 创建启动Activity的任务final ClientTransaction clientTransaction ClientTransaction.obtain(proc.getThread(), r.appToken);final DisplayContent dc r.getDisplay().mDisplayContent;// 非常重要添加 LaunchActivityItem callback备注一clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),System.identityHashCode(r), r.info,mergedConfiguration.getGlobalConfiguration(),mergedConfiguration.getOverrideConfiguration(), r.compat,r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),r.icicle, r.persistentState, results, newIntents,dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),r.assistToken));//..// 执行启动Activity的任务mService.getLifecycleManager().scheduleTransaction(clientTransaction);//} //..return true;} 请记住备注一这里添加了个LaunchActivityItem作为CallBack它很重要。但是在讲解它之前我们首先看ClientTransaction.obtain方法: public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {ClientTransaction instance ObjectPool.obtain(ClientTransaction.class);if (instance null) {instance new ClientTransaction();}instance.mClient client;instance.mActivityToken activityToken;return instance;} 代码很简单就是初始化ClientTransaction关键点在于mClient成员变量。它是一个IApplicationThread类型的没错它是AIDL。而它的具体实现在实现是ActivityThread.ApplicationThread是ActivityThread的一个内部类。紧接着看mService.getLifecycleManager().scheduleTransaction(transaction);这段代码调用了ClientLifecycleManager.scheduleTransaction: void scheduleTransaction(ClientTransaction transaction) throws RemoteException {//..transaction.schedule();//..} 紧接着调用ClientTransaction.schedule方法 public void schedule() throws RemoteException {mClient.scheduleTransaction(this);} 而这个mClient就是我们的AIDL客户端(AMS)。使用它向我们的服务端(ActivityThread)发送请求它实现就在ActivityThread$ApplicationThread中。 ActivityThread接受请求开始创建 接下来就是ActivityThread处理请求了 Overridepublic void scheduleTransaction(ClientTransaction transaction) throws RemoteException {ActivityThread.this.scheduleTransaction(transaction);}由于 ActivityThread继承自ClientTransactionHandler所以scheduleTransaction会调用ClientTransactionHandler. scheduleTransaction方法 void scheduleTransaction(ClientTransaction transaction) {transaction.preExecute(this);sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}而sendMessage定义在ActivityThread中它有多个重载方法最终会执行 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {if (DEBUG_MESSAGES) {Slog.v(TAG,SCHEDULE what mH.codeToString(what) : arg1 / obj);}Message msg Message.obtain();msg.what what;msg.obj obj;msg.arg1 arg1;msg.arg2 arg2;if (async) {msg.setAsynchronous(true);}mH.sendMessage(msg);} 很明显这是一个Handler接着看mH的具体实现 public void handleMessage(Message msg) {//..switch (msg.what) {//..//执行生命周期的调度工作case EXECUTE_TRANSACTION:final ClientTransaction transaction (ClientTransaction) msg.obj;mTransactionExecutor.execute(transaction);//..break;//..}//.. } 很明显AMS使用Binder请求ActivityThread创建Activity然后ActivityThread通过Handler机制向TransactionExecutor发送创建的请求。 紧接着看TransactionExecutor的execute方法 public void execute(ClientTransaction transaction) {//..executeCallbacks(transaction);//.. } 关键方法就是调用了executeCallbacks public void executeCallbacks(ClientTransaction transaction) {final ListClientTransactionItem callbacks transaction.getCallbacks();//..final int size callbacks.size();for (int i 0; i size; i) {//..item.execute(mTransactionHandler, token, mPendingActions);item.postExecute(mTransactionHandler, token, mPendingActions);//..}} 没错在这里就用到了CallBack了这里面必定有刚刚备注一里提到的LaunchActivityItem。我们直接看它的execute方法 public void execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {//..client.handleLaunchActivity(r, pendingActions, null /* customIntent */);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);} 调用了ClientTransactionHandler的handleLaunchActivity方法。还记得上文说的ActivityThread继承自ClientTransactionHandler。其实这个ClientTransactionHandler就可以认为是ActivityThread其中handleLaunchActivity的实现如下 public Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, Intent customIntent) {final Activity a performLaunchActivity(r, customIntent);}只留下关键代码调用了performLaunchActivity方法: private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {ActivityInfo aInfo r.activityInfo;//..//创建上下文环境ContextImpl appContext createBaseContextForActivity(r);Activity activity null;try {//重点一java.lang.ClassLoader cl appContext.getClassLoader();activity mInstrumentation.newActivity(cl, component.getClassName(), r.intent);StrictMode.incrementExpectedActivityCount(activity.getClass());r.intent.setExtrasClassLoader(cl);r.intent.prepareToEnterProcess();if (r.state ! null) {r.state.setClassLoader(cl);}} catch (Exception e) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException(Unable to instantiate activity component : e.toString(), e);}}try {Application app r.packageInfo.makeApplication(false, mInstrumentation);//..if (activity ! null) {//..//重点二activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window, r.configCallback,r.assistToken);//设置主题int theme r.activityInfo.getThemeResource();if (theme ! 0) {activity.setTheme(theme);}//重点三if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}//..}//..} catch (SuperNotCalledException e) {throw e;} catch (Exception e) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException(Unable to start activity component : e.toString(), e);}}return activity;} 最最最重要的来了我们关注代码注释里的几点 重点一通过反射创建Activity 重点二调用了Activity.attach()方法 重点三通过Instrumentation对象执行Activity的onCreate()方法。 到这里Activity就算是创建完成了。 总结 到这里Activity的创建就完成了。放一个极简版序列图 其中Ams为ActivityManagerServiceAndroid最近一些较新的版本为了解决ActivityManagerService臃肿的问题引入了ActivityTaskManagerService来分担Ams工作就是图中的Atms。 Activity的关系大致如下图 如上图所示除了启动Activity的进程和Activity运行的进程可能为同一进程它们互为不同进程。当要创建一个Activity时 如果Activity所依赖的进程已经存在那么流程为Step:1-2。如果启动进程和运行进程是一个那么该过程只涉及到两个进程启动进程和AMS进程否则就是三个启动进程、运行进程和AMS进程如果Activity所依赖的进程不存在那么流程为Step:1-3-4-2。 本文只讲述了请求创建的流程其中省略了很多其他操作。包括Activity生命周期的调用都是由Instrumentation对象来调用的、进程的创建、activity的attach等其他重要操作。相关知识可以由于能力有限大家可自行查看Android源码自行了解。 最后推荐一些比较好的博客供参考学习 ActivityRecord、TaskRecord、ActivityStack以及Activity启动模式详解四大组件之ActivityRecord深入理解ActivityRecord、TaskRecord、ActivityStack的作用及关系framework之Activity启动流程Android启动流程源码解析
http://www.sczhlp.com/news/214099/

相关文章:

  • 做网站wamp和xamp初中毕业怎么样提升学历
  • 太原模板建站平台郑州网站营销汉狮
  • 怎么制作网站店铺成都工商注册咨询电话
  • 制作网站软件作品视频音乐网站怎样建设
  • 南京网络推广建站湖南建筑行业
  • 上海网站建设沪icp备如何加强网站建设和信息宣传
  • 做网站要学的教程网站建设与维护难不难
  • 网站是怎么做新手引导sql数据库添加网站
  • 男女做爰视频网站文库网站开发建设
  • 网站建设格局做传销网站违法的吗
  • 自助建个人网站哪个好创建一个网站的步骤
  • 兰州市七里河建设局网站天津团购鲜花的网站建设
  • 网站域名选择的原则物业公司网站设计
  • 网站的建设与维护需要资质吗公司网站设计 优帮云
  • 优秀企业网站的特点苏州建设档案馆官方网站
  • 学校网站建设教程wordpress触屏主题
  • 网站的查询功能是怎样做的中企动力科技股份官网
  • 泉州找工作哪个网站好网站域名跳转怎么弄
  • 法治建设网站作用建设招投标网
  • 建设网站用什么软件排版秀米h5制作教程
  • 分析网站统计对网络营销的价值东营网站制作方案
  • 优惠券网站要怎么做的花卉网站建设策划
  • 自己的网站做怎样的优化调整做壁纸壁的网站有什么
  • 网站建设人员岗位设置新年贺卡图片 手工制作
  • https://www.luogu.com.cn/problem/CF1635E
  • ZR 2025 NOIP 二十连测 Day 5
  • SpringBoot整合Redis教程
  • seo网站建设博采网络股吧
  • 太原企业网站seo台式机做网站服务器
  • 电器网站模板越秀区网站建设公司