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

wordpress怎么安装上服务器沈阳百度seo

wordpress怎么安装上服务器,沈阳百度seo,营销网络怎么写,恒通建设集团有限公司网站0. 写在前面 本文基于 Android8.0源码#xff0c;和Android9.0大同小异#xff0c;但和Android10.0差别非常大#xff01;新版改用ATM来管理Activity的启动#xff0c;Activity的生命周期也通过XXXItem来管理。由于我分析的Activity启动流程就是基于Android8/9的#xff…0. 写在前面 本文基于 Android8.0源码和Android9.0大同小异但和Android10.0差别非常大新版改用ATM来管理Activity的启动Activity的生命周期也通过XXXItem来管理。由于我分析的Activity启动流程就是基于Android8/9的所以本文仍然使用Android8源码来探索 Activity 栈管理。后续有时间再学习整理Android10.0的内容。 1. 前置知识 1.1 Activity栈管理相关类 ActivityStackSupervisor Activity栈的管理人 ActivityDisplay 表示一个屏幕Android支持三种屏幕主屏幕外接屏幕虚拟屏幕投屏【这个介绍是从其他地方看来的并不确定】。一般在手机上只有主屏幕此时ActivityStackSupervisor与ActivityDisplay都是系统唯一的 TaskRecord 是ActivityTask的记录TaskRecord是Activity栈的重要管理单元。形象一点理解记得启动模式的 singleTask 吧意思就是让这个Activity在单独的TaskRecord中启动。“Task:任务。 ActivityRecord 记录着每个Activity的信息ActivityRecord和Activity一一对应。 ActivityStack 是ActivityRecord和TaskRecord两者的统一上司记录着ActivityRecord和TaskRecord的状态。 如果在只有主屏幕的设备上他们之间的关系大概是这样子的 可以理解为一个屏幕上可能会有很多个APP进程每个APP进程对应一个ActivityStack也就是activity栈其中由于Activity的启动模式不同又形成了若干个TaskRecord其中包含着若干个ActivityRecord。 1.2 Activity 的四种启动模式以及启动标识符 Standard 标准启动模式启动Activity的时候向发起人的Task顶直接添加即可返回时依次退出。 SingleTop 栈顶唯一如果栈顶Activity不是要启动的Activity则会创建一个新的Activity实例但如果栈顶Activity就是我们要启动的Activity就只会调用onNewIntent而不去再重新创建一个实例。相比StandardStandard不论如何都会创建一个新的实例。 SingleTask 栈内唯一。如果发起启动的ActivityRecord所在的TaskRecord中有要启动的Activity对应的ActivityRecord则首先将TaskRecord中目标Activity之上的所有ActivityRecord全都弹出然后将所在TaskRecord变为ActivityStack的栈顶。 如果发起启动的ActivityRecord所在的TaskRecord中没有要启动的Activity对应的ActivityRecord则会在栈顶新建一个TaskRecord并向其中实例化一个需要启动的Activity对应的ActivityRecord。 SingleInstance 独占一个TaskRecord。启动时在ActivityStack中查找是否有相同的Activity如果有则用这个独占TaskRecord的ActivityRecord对应的Activity。否则新建一个TaskRecord里面只有它存在。由singleInstance发起的启动不论是谁都会在另一个task中启动。 Activity的Flags标志位 FLAG_ACTIVITY_NEW_TASK作用为指定 singleTask 启动模式FLAG_ACTIVITY_SINGLE_TOP作用为指定 singleTop 启动模式FLAG_ACTIVITY_CLEAR_TOP与FLAG_ACTIVITY_NEW_TASK连用主要用在复用Activity上在TaskRecord中复用的ActivityRecord之上的所有AR都要退出FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS具有这个标志位的Activity将不会出现在历史列表中。 2. 定位到AMS进行栈管理的代码 AMS接收到启动Activity的请求时将实际Activity的启动任务分配给了ActivityStarter来处理最后是通过ActivityStarter.startActivityUnchecked()与ActivityStackSupervisor合作完成的Activity栈管理。我们大概的来跟踪一遍这部分代码 ActivityManagerService binder通信告知ActivityManagerService需要启动activity。回顾binder通信的知识需要注意的是 ActivityManagerService 是一个binder实体是一个服务IActivityManager.Stub它对外提供的方法都是由IActivityManager接口定义好的所以我们能看到这些方法上加了 Override 注解。AMS调用到了startActivity方法 Override public final int startActivity(...) {return startActivityAsUser(...); } Override public final int startActivityAsUser(...) {//进入到了ActivityStarterreturn mActivityStarter.startActivityMayWait(...); }ActivityStarter 在startActivityMayWait()中对intent做了一些处理然后逐层调用重载的几个startActivity()方法 //1.对intent做一些处理 final int startActivityMayWait(){startActivityLocked(); } //2.继续往里调用 int startActivityLocked(){startActivity(); } //3.做一些权限判断在这里new了一个ActivityRecord为要启动的activity提前创造好了空壳ActivityRecord int startActivity(){return startActivity(); } //4.继续调用 int startActivity(){startActivityUnchecked(); } //5.来到核心 int startActivityUncheckd(){//这会根据各种启动模式设定进行activity的启动 }在具体分析代码之前我们来看一下startActivityUnchecked()最开头的 computeLaunchingTaskFlags()看看启动模式标志位的设计然后再分析后续代码。 private void computeLaunchingTaskFlags() { //mSourceRecord当前Activity是被它发起启动的//mInTask:所在TaskRecord//mInTask.getStack()为这个TaskRecord所在的ActivityStackif (mSourceRecord null mInTask ! null mInTask.getStack() ! null) {final Intent baseIntent mInTask.getBaseIntent();final ActivityRecord root mInTask.getRootActivity();//一些错误终止if (root null) {//如果TaskRecord是空的final int flagsOfInterest FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK| FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;mLaunchFlags (mLaunchFlags ~flagsOfInterest)| (baseIntent.getFlags() flagsOfInterest);//将flags整合起来放到MIntent中mIntent.setFlags(mLaunchFlags);mInTask.setIntent(mStartActivity);mAddingToTask true;} else if ((mLaunchFlags FLAG_ACTIVITY_NEW_TASK) ! 0) {//如果TaskRecord非空而且标志位为 FLAG_ACTIVITY_NEW_TASK//那么新的ActivityRecord应当在新的TaskRecord中建立所以mAddingToTask falsemAddingToTask false;} else {//如果要在当前的TaskRecord中建立mAddingToTask truemAddingToTask true;}mReuseTask mInTask;} else {mInTask null;//如果是这是个起源任务也就是最初的一个task。换句话说这个activity是第一个activityif ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) mSourceRecord ! null mSourceRecord.isFreeform()) {mAddingToTask true;}}//如果这个Activity就是第一个Activityif (mInTask null) {if (mSourceRecord null) {//这个activity不可能是被其他activity唤起的例如app进程启动后的第一个activity。那么他的启动必然是在新的task中的。if ((mLaunchFlags FLAG_ACTIVITY_NEW_TASK) 0 mInTask null) {Slog.w(TAG, startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: mIntent);mLaunchFlags | FLAG_ACTIVITY_NEW_TASK;}} else if (mSourceRecord.launchMode LAUNCH_SINGLE_INSTANCE) {//如果发起者的启动模式是singleInstance那么由它启动的activity都应当在一个新的TaskRecord中mLaunchFlags | FLAG_ACTIVITY_NEW_TASK;} else if (mLaunchSingleInstance || mLaunchSingleTask) {// 如果要启动的Activity的启动模式是singleInstance或者singleTask且当前环境下是没有一个所在TaskRecord那么就应当新建一个Task。mLaunchFlags | FLAG_ACTIVITY_NEW_TASK;}} }我们再来看一下 startActivityUnchecked()中getReusableIntentActivity()是如何获取一个可复用的Activity的 private ActivityRecord getReusableIntentActivity() {// 新的ActivityRecord是否要放到现存的TaskRecord中呢根据标志位做一些判断boolean putIntoExistingTask ((mLaunchFlags FLAG_ACTIVITY_NEW_TASK) ! 0 (mLaunchFlags FLAG_ACTIVITY_MULTIPLE_TASK) 0)|| mLaunchSingleInstance || mLaunchSingleTask;putIntoExistingTask mInTask null mStartActivity.resultTo null;//接下来就尝试获取一个目标ActivityActivityRecord intentActivity null;if (mOptions ! null mOptions.getLaunchTaskId() ! -1) {//指定一个TaskRecord获取这个TaskRecord的顶部Activity来复用可能是nullfinal TaskRecord task mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());intentActivity task ! null ? task.getTopActivity() : null;} else if (putIntoExistingTask) {//如果没有指定但是确实要放到一个现存的TaskRecord中就需要看情况了if (mLaunchSingleInstance) {//1.如果新Activity的启动模式为 singleInstance那么就要在已存在的所有TaskRecord中找找它是否存在如果存在则复用。和singleInstance的基础介绍保持一致intentActivity mSupervisor.findActivityLocked(mIntent, mStartActivity.info,mStartActivity.isHomeActivity());} else if ((mLaunchFlags FLAG_ACTIVITY_LAUNCH_ADJACENT) ! 0) {//2.如果启动标志位为FLAG_ACTIVITY_LAUNCH_ADJACENT这个比较特殊是多窗口启动ActivityintentActivity mSupervisor.findActivityLocked(mIntent, mStartActivity.info,!mLaunchSingleTask);} else {// 否则寻找一个合适的TaskRecord来放入intentActivity mSupervisor.findTaskLocked(mStartActivity, mSourceDisplayId);}}return intentActivity; }3. 根据不同的启动模式来分析代码逻辑 3.1 Standard 1. standard 普通启动模式需要注意如果是第一个Activity它一定是new_task标志位也就是即使在xml设置了standard它也是new_task启动。那么如果一个Activity是以Standard模式启动的它一定有mSourceRecord即发起它启动的Activity。 在 startActivityUnchecked() 中一路跳过if()判断来到这个方法的最后 private int startActivityUnchecked(){computeLaunchingTaskFlags();//由于找不到一个合适的栈放入reusedActivity nullActivityRecord reusedActivity getReusableIntentActivity();//...跳过了很多不通过的判断语句//1. 如果有可复用的Activity//2. 如果栈顶Activity就是自己//最终来到这里↓//到这里还是standard的启动模式就一定有sourceActivity而且这个sourceActivity一定不是singleInstance否则在修正flag的时候当前新的activity就被修正为new_task了if (mStartActivity.resultTo null mInTask null !mAddingToTask (mLaunchFlags FLAG_ACTIVITY_NEW_TASK) ! 0) {newTask true;result setTaskFromReuseOrCreateNewTask(taskToAffiliate, preferredLaunchStackId, topStack);} else if (mSourceRecord ! null) {//所以会进入到这里result setTaskFromSourceRecord();} else if (mInTask ! null) {result setTaskFromInTask();} else {setTaskToCurrentTopOrCreateNewTask();}if (result ! START_SUCCESS) {return result;} }我们只截取setTaskFromSourceRecord()核心代码来看 private int setTaskFromSourceRecord(){//...//最后来到这里// An existing activity is starting this new activity, so we want to keep the new one in// the same task as the one that is starting it.addOrReparentStartingActivity(sourceTask, setTaskFromSourceRecord);return START_SUCCESS; }然后进入 addOrReparentStartingActivity() private void addOrReparentStartingActivity(TaskRecord parent, String reason) {if (mStartActivity.getTask() null || mStartActivity.getTask() parent) {parent.addActivityToTop(mStartActivity);} else {//会进入到这里mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);} }最后执行到 TaskRecord.addActivityAtIndex()最后将新ActivityRecord加到了TaskRecord的mActivities([ActivityRecord集合])中去mActivities.add(index, r); 到此standard启动模式就完成了入栈操作。 2. standard Intent.FLAG_ACTIVITY_CLEAR_TOP 如果不仅是standard启动模式还增设了一个启动标识符 Intent.FLAG_ACTIVITY_CLEAR_TOP如果原先TaskRecord中有它存在就会进行 singleTask 的任务具体在 singleTask中谈到实现。 3.2 singleTop 由于singleTop启动模式的Activity也不会得到 reusableIntentActivity所以会跳过 startActivityUnchecked()的第一个if判断。但它将进入第二个逻辑块如果当前的activity是栈顶元素将会复用它。当然如果栈顶是其他activity那么当前新activity的启动模式将会和standard一样了。 我们来看一下栈顶就是这个activity的情况仍然看到ActivityStarter的startActivityUnchecked() // If the activity being launched is the same as the one currently at the top, then // we need to check if it should only be launched once. final ActivityStack topStack mSupervisor.mFocusedStack; final ActivityRecord topFocused topStack.topActivity(); final ActivityRecord top topStack.topRunningNonDelayedActivityLocked(mNotTop); //如果当前栈顶activity就是自己的话就dontStart不用再start了 final boolean dontStart top ! null mStartActivity.resultTo null top.realActivity.equals(mStartActivity.realActivity) top.userId mStartActivity.userId top.app ! null top.app.thread ! null ((mLaunchFlags FLAG_ACTIVITY_SINGLE_TOP) ! 0|| mLaunchSingleTop || mLaunchSingleTask); if (dontStart) {//也就是可以直接复用if (mDoResume) {//首先让windowmanager.executeAppTransition()mSupervisor.resumeFocusedStackTopActivityLocked();}//然后直接分发onNewIntent事件deliverNewIntent(top);return START_DELIVERED_TO_TOP; }我们来看一下deliverNewIntent()是如何把消息发给activity的 //ActivityStarter private void deliverNewIntent(ActivityRecord activity) {if (mIntentDelivered) {return;}ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTask());//调用到ActivityRecord的deliverNewIntentLocked()activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,mStartActivity.launchedFromPackage);mIntentDelivered true; }//ActivityRecord final void deliverNewIntentLocked(){//如果app正常app.thread.scheduleNewIntent(rintent,appToken,statePAUSED);//如果app异常将会把rintent记录未来dump的时候可以获知if(unsent){addNewIntentLocked(rintent);} } 看到这就很清晰了就是通过binder通信告知了app进程现在需要处理onNewIntent任务。我们顺带简单看一下ActivityThread如何处理applicationThread这个binder实体接收到的newIntent通知 //ApplicationThread in ActivityThread.java public final void scheduleNewIntent(ListReferrerIntent intents, IBinder token, boolean andPause) {NewIntentData data new NewIntentData();data.intents intents;data.token token;data.andPause andPause;sendMessage(H.NEW_INTENT, data); }接着由mH来handleNewIntent() case NEW_INTENT:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, activityNewIntent);handleNewIntent((NewIntentData)msg.obj);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;handleNewIntent(NewIntentData data)-performNewIntents() 如果这个复用的activity还是resume状态先让他onPause()然后再给它发送newIntent并通知其onResume() void performNewIntents(IBinder token, ListReferrerIntent intents, boolean andPause) {final ActivityClientRecord r mActivities.get(token);if (r null) {return;}final boolean resumed !r.paused;if (resumed) {//如果复用的activity目前还是resume状态先让他onPausemInstrumentation.callActivityOnPause(r.activity);}deliverNewIntents(r, intents);if (resumed) {r.activity.performResume();r.activity.mTemporaryPause false;}if (r.paused andPause) {// In this case the activity was in the paused state when we delivered the intent,// to guarantee onResume gets called after onNewIntent we temporarily resume the// activity and pause again as the caller wanted.performResumeActivity(token, false, performNewIntents);performPauseActivityIfNeeded(r, performNewIntents);} }其中 deliverNewIntents() 回调了activity的onNewIntent() private void deliverNewIntents(ActivityClientRecord r, ListReferrerIntent intents) {final int N intents.size();for (int i0; iN; i) {ReferrerIntent intent intents.get(i);intent.setExtrasClassLoader(r.activity.getClassLoader());intent.prepareToEnterProcess();//通知fragmentsr.activity.mFragments.noteStateNotSaved();//通知onNewIntentmInstrumentation.callActivityOnNewIntent(r.activity, intent);} }3.3 singleTask “栈内唯一”的说法并不合适实际上是TaskRecord内唯一。根据我画的这张图先来大概理解一下再进入源码分析 当前栈结构为最左情况现在B_Activity要启动A_Activity我们假定B_Activity的启动模式为standardA_Activity的启动模式为singleTask由于A_Activity的启动模式为singleTask就需要尝试查找能否复用。在ActivityStack中的所有TaskRecord中遍历查找是否存在A_Activity发现存在于下面这个TaskRecord中。先将该TaskRecord中A_Activity之上其他的ActivityRecord全都弹出然后将该TaskRecord浮动转移到所在ActivityStack的最顶端。 即使是C_Activity发起的启动A_Activity只要ActivityStack中有一个TaskRecord存在A_Activity就会对这个TaskRecord进行清除内部上方其他ActivityRecord的行为。流程图和上图一模一样换一种解释换一种解释说法 C_Activity的启动模式为 standard,A_Activity的启动模式为 singleTask由于A_Activity的启动模式为singleTask就需要尝试查找能否复用。在ActivityStack中的所有TaskRecord中遍历查找是否存在A_Activity发现存在于下面这个TaskRecord中。先将该TaskRecord中A_Activity之上其他的ActivityRecord全都弹出然后将该TaskRecord浮动转移到所在ActivityStack的最顶端。C_Activity所在的TaskRecord并没有被移除仅仅是被转移到了ActivityStack的下面而已。 继续分析源码我们又来到了ActivityStarter的startActivityUnchecked()首先尝试getReusableIntentActivity() 获取可复用的Activity private ActivityRecord getReusableIntentActivity(){boolean putIntoExistingTask ((mLaunchFlags FLAG_ACTIVITY_NEW_TASK) ! 0 (mLaunchFlags FLAG_ACTIVITY_MULTIPLE_TASK) 0)|| mLaunchSingleInstance || mLaunchSingleTask;//true//...else{intentActivity mSupervisor.findTaskLocked();}return intentActivity; }mSupervisor.findTaskLocked()将会遍历所有的TaskRecord查看是否有目标activity如果有则作为intentActivity返回出去如果没有就是null。这两个情况都需要我们讨论。先来讨论一下有TaskRecord存在这个ActivityRecord的情况 private int startActivityUnchecked(){//...ActivityRecord reusedActivity getReusableIntentActivity();//由于找到了一个可复用的activity进入到下面这个判断体内if(reusedActivity ! null){//由于singleTask启动模式所以会进到下面if ((mLaunchFlags FLAG_ACTIVITY_CLEAR_TOP) ! 0|| isDocumentLaunchesIntoExisting(mLaunchFlags)|| mLaunchSingleInstance || mLaunchSingleTask) {//拿到所在的TaskRecordfinal TaskRecord task reusedActivity.getTask();//将TaskRecord中在它之上的所有ActivityRecord全都移除final ActivityRecord top task.performClearTaskForReuseLocked(mStartActivity,mLaunchFlags);if (top ! null) {if (top.frontOfTask) {top.getTask().setIntent(mStartActivity);}deliverNewIntent(top);}}//之后可能需要将这个TaskRecord转移到ActivityStack的顶部也就是栈顶内部调整位置的逻辑就不进去看了reusedActivity setTargetStackAndMoveToFrontIfNeeded(reusedActivity);} }接下来的逻辑就是发送newIntent到app进程如果这个activity之前是pause状态的话还会performResumeActivity()在此之前会先行回调onNewIntent() 3.3 singleInstance 它不仅在ActivityStack栈内唯一而且还独占一个TaskRecord。可以理解为它位分最高。它的代码逻辑很简单了结合singleTask来看就好了。其他需要注意的地方是如果由它启动任何一个activity都将被设置为 flag_activity_new_task模式 我们又回到ActivityStarter中看到startActivityUnchecked()的computeLaunchingTaskFlags()我们只关注singleInstance作为源sourceRecord启动别的activity的情况 private void computeLaunchingTaskFlags() {//...if (mInTask null) {if (mSourceRecord null) {//...} else if (mSourceRecord.launchMode LAUNCH_SINGLE_INSTANCE) {//有源而且源是 singleInstance 的启动模式//那么不论你之前的flag是什么样的都会被标记上 flag_activity_new_task!!mLaunchFlags | FLAG_ACTIVITY_NEW_TASK;} else if (mLaunchSingleInstance || mLaunchSingleTask) {mLaunchFlags | FLAG_ACTIVITY_NEW_TASK;}} }4. 讨论一下进程第一个Activity在这里的启动是如何表现的 其实我们之前也看了如果没有源头mSourceRecord也没有mInTask这就是第一个activity那么它的启动标识符就一定会被加上 FLAG_ACTIVITY_NEW_TASK。也就是说他会是这个APP进程的ActivityStack的第一个TaskRecord的第一个ActivityRecord。 说到这里我们还需要将它和之前Activity启动流程的步骤做一个整合我们来分析一下 我们不应该聚焦在AMS通知application初始化而应该再往前看一点从点击桌面图标到打开APP进程。再点击桌面图标的时候其实就是startActivity()这个我们之前讨论的很全面了 AMS接收到startActivity()的通知将任务交给了ActivityStarter ActivityStarter在不断调用startActivity()的过程中为要启动的Activity创建了一个空壳ActivityRecord 最后ActivityStarter来到了startActivityUnchecked()由于这个ActivityRecord还没有任何绑定所以最后进入到了ActivityStackSupervisor.resumeFocusedStackTopActivityLocked() boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (!readyToResume()) {return false;}//进入到resumeTopActivityUncheckedLocked()if (targetStack ! null isFocusedStack(targetStack)) {return //然后进入到resumeTopActivityInnerLocked()这部分代码特别长就不贴了在这里面会调用startSpecificActivityLocked()targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}return false; }ActivityStackSupervisor调用到startSpecificActivityLocked()会进行一个检查看看这个activity的app进程是否运行了 void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {// Is this activitys application already running?ProcessRecord app mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);r.getStack().setLaunchTime(r);//如果这个ActivityRecord的进程已经在运行了进入这里if (app ! null app.thread ! null) {}//如果没有则先启动进程~//通过AMS的startProcessLocked()来启动进程mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,activity, r.intent.getComponent(), false, false, true); }AMS.startProcessLocked()中间会调用到 Process.start() private final void startProcessLocked(...){//...startResult Process.start(...); }然后就是我们熟悉的zygote.fork()的任务了 然后。我们需要聚焦到AMS在通知完application初始化之后又通知了ActivityStackSupervisor.attachApplicationLocked()在这里面进行了栈管理。我们来到ActivityStackSupervisor: //ActivityStackSupervisor(栈管理者) //这里的ProcessRecord中管理着整个进程的各种信息包括运行中的ActivityRecord以及ServiceRecord、ConnectionRecord、ReceiverList、ContentProvider等各种信息 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {final String processName app.processName;boolean didSomething false;//遍历所有屏幕我们之前谈过安卓设备可能有主屏幕、外界屏幕、虚拟屏幕一般情况下手机就只有主屏幕。还可能有分屏。for (int displayNdx mActivityDisplays.size() - 1; displayNdx 0; --displayNdx) {//拿到一个屏幕下所有ActivityStackArrayListActivityStack stacks mActivityDisplays.valueAt(displayNdx).mStacks;for (int stackNdx stacks.size() - 1; stackNdx 0; --stackNdx) {final ActivityStack stack stacks.get(stackNdx);//找到当前显示的/持有焦点的ActivityStack//这个activitystack的任务是接收用户输入或者启动另一个activityif (!isFocusedStack(stack)) {continue;}//获取所有正在运行且可见的activity放到mTmpActivityList中stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);//获取正在运行的Activity中的最顶端ActivityRecordfinal ActivityRecord top stack.topRunningActivityLocked();final int size mTmpActivityList.size();for (int i 0; i size; i) {final ActivityRecord activity mTmpActivityList.get(i);//这个activity的processRecord为空但它的processName以及有了这是app进程初始在某个时候注册的ActivityRecordif (activity.app null app.uid activity.info.applicationInfo.uid processName.equals(activity.processName)) {//判断活动的activity的进程是不是和我要启动的activity的进程一致如果是就进入到这里面来try {//开启activityif (realStartActivityLocked(activity, app,top activity /* andResume */, true /* checkConfig */)) {didSomething true;}} catch (RemoteException e) {Slog.w(TAG, Exception in new application when starting activity top.intent.getComponent().flattenToShortString(), e);throw e;}}}}}if (!didSomething) {ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);}return didSomething; } 当前APP的ActivityStack有一个空的ActivityRecord需要realStartActivityLocked()来真正启动ActivityRecord对应的activity。它这个时候还是个空壳。 进入到realStartActvitiyLocked() //ActviityStackSupervisor final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig){//这个taskrecord目前只有一个空壳activityRecordfinal TaskRecord task r.getTask();//这个activityStack目前也只有一个TaskRecord和一个空壳activityrecordfinal ActivityStack stack task.getStack();r.app app;//为这个ActivityRecord绑定ProcessRecordint idx app.activities.indexOf(r);//为ProcessRecord绑定activityRecordif (idx 0) {app.activities.add(r);}//binder通信通知app进程可以启动activity。注意这里的r是ActivityRecord这是个空壳但是到这里它的意义就是APP进程的第一个activity。app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,...);}至此activity启动完成。 总结 从一个LauncherActivity到APP进程的activityActivity的栈在其中的工作大致如下 Activity的启动一般可以通过startActivity()来进行通过Instrumentation.execStartActivity()最终会通知到AMS来进行Activity的启动。AMS通过binder线程获知了需要启动Activity的任务让ActivityStarter去完成activity的启动。ActivityStarter在一连串的startActivity()调用过程中为要启动的Activity创建了一个ActivityRecord。最后进入到startActivityUnchecked()根据Activity的启动模式与启动标识符的不同进行不同的处理。如果这个Activity是新进程的Activity将会通知AMS先进行APP进程的启动APP进程的application启动完成后会通知AMSapplication初始完成并将APP进程的binder代理交给AMSAMS再通过ActivityStartSupervisor来realStartActivityLocked()-app.thread.scheduleLaunchActivity()来通知APP进程可以启动activity了。如果这个Activity是本进程发起的启动那么就会根据发起者Activity的启动模式以及新Activity的启动模式综合判断是复用Activity接着调用newIntent()呢还是新建一个Activity然后也进入到realStartActivityLocked()-app.thread.scheduleLaunchActivity()来启动新的Activity.
http://www.w-s-a.com/news/890788/

相关文章:

  • 公司营业执照可以做几个网站一家专门做母婴的网站
  • 网站建设商标属于哪个类别搜狗seo快速排名公司
  • 织梦做商城网站企业网络建站
  • 网站后期维护都有什么wordpress首页加图片
  • 展会网站怎么做网页设计与制作教程版徐洪亮课后答案
  • 石景山网站建设设计公司建设网站怎么建立服务器
  • 本地生活服务平台app网站关键词优化原理
  • 建网站的公司叫什么重庆论坛建站模板
  • 湖北网站制作公司银川网站建设哪家不错
  • 网站后台演示地址服装网站建设公司推荐
  • 湖北钟祥建设局网站旅游哪个网站最好
  • 浙江建设工程信息网站辽宁建设工程信息网场内业绩什么意思
  • 郑州做网站公司 汉狮网络专业图片搜集网站怎么做
  • 网站托管是什么品牌推广营销平台
  • 制作网站的难度贵州省兴义市建设局网站
  • 永春建设局网站室内设计师培训班学费多少
  • 做仿站如何获取网站源码windows2012做网站
  • 网站建设最好的公司东莞外贸网站
  • 普兰店网站建设一般做网站什么价格
  • 网站建设的发展目标甘肃网站设计公司
  • 常州西站建设规划室内装修设计学校哪里好
  • 大连网站制作选择ls15227如何编辑网站
  • 网站发稿平台迪士尼网站是谁做的
  • 常州有哪些好的网站建设案例wordpress 360 插件
  • 模板网站有后台么柳城网站建设
  • 地方门户网站制作一级做c爱片的网站
  • 自己上传图片做动漫图网站北京福田汽车
  • 一级a做爰片免费网站录像ps做网站图片水印
  • 网页广告投放成都优化推广公司
  • 网站开发 印花税网页制作站点