Android启动过程(三)ActivityManagerService----2

Android启动过程(三)ActivityManagerService----1 继续上一篇

Step3@startActivityLocked(1),如果此时还没有找到合适的目标Activity来处理Intent,或者这个目标的ActivityInfo为空,都说明这个Intent 没有办法继续处理了,因此程序会直接报错返回。

Step4@startActivityLocked(1),上面的判断通过后,还需要检查调用者是否有权限来启动指定的Activity。具体如下所示

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
 final int startAnyPerm = mService.checkPermission(
                START_ANY_ACTIVITY, callingPid, callingUid);
        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
callingUid, aInfo.applicationInfo.uid, aInfo.exported);

上述这两个权限检查必须全部通过,否则会抛出SecurityException。

Step5@startActivityLocked(1),生成一个ActivityRecord变量r,记录当前的各项判断结果,然后进一步调用startActivityUncheckedLocked----这个函数将涉及一系列启动模式和Intent 标志的处理,建议读者穿插阅读ActivityTask小节中对这些标志的说明。

接下来我们再详细讲解startActivityUnCheckedLocked这个函数。

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

       final int startActivityUncheckedLocked(ActivityRecord r,
        ActivityRecord sourceRecord, int startFlags, boolean doResume,
        Bundle options) {
    //...  
    //此时launcheFlags为0
    int launchFlags = intent.getFlags();      
    //notTop为null
    ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
            != 0 ? r : null;
    //默认情况下startFlags不会设置START_FLAG_ONLY_IF_NEEDED    
    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
        //...这里的代码不会执行
    }    
    //r.launchMode = ActivityInfo.LAUNCH_SINGLE_TASK 
    if (sourceRecord == null) {
       //这里的代码不会执行  
    } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        //这里的代码不会执行    
    } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    }
    //此时r.resultTo!=null launchFlags设置了Intent.FLAG_ACTIVITY_NEW_TASK
    if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
       //...
        r.resultTo = null;
    }       
    //addingToTask如果为true表示正在添加至某个task,后续需要将r添加至sourceRecord所在的task
    boolean addingToTask = false;
    //movedHome表示是否移动home task
    boolean movedHome = false; 
    TaskRecord reuseTask = null;       
    if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        //此时 r.resultTo = null
        if (r.resultTo == null) {
            //此时找到的taskTop是Activity A的ActivityRecord,
            //因为Actvity B和A的ActivityRecord所在的Task是相关的
            ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
                    ? findTaskLocked(intent, r.info)
                    : findActivityLocked(intent, r.info);
            //找到了相关task        
            if (taskTop != null) {
                //重设task的intent
                if (taskTop.task.intent == null) {
                     //...
                }
                //此时找到的task已在栈顶
                ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop);
                if (curTop != null && curTop.task != taskTop.task) {
                    //... 这里的代码不会执行 
                }
                //launchFlags为0
                if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                    taskTop = resetTaskIfNeededLocked(taskTop, r);
                }
                //... 一般情况下startFlags 不会设置 START_FLAG_ONLY_IF_NEEDED
                if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED)  != 0) {
                    //...
                } 
                // ==================== begin
                // launchFlags此时为0
                if ((launchFlags &
                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
                     //...这里的代码不执行
                } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
                        || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
                        || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                    // r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
                    // 故此会进入该分支
                    //因为B还从未启动,故此得到的top为null
                    ActivityRecord top = performClearTaskLocked(
                            taskTop.task.taskId, r, launchFlags);
                    if (top != null) {
                        //...这里的代码不执行 
                    } else { 
                        addingToTask = true; 
                        sourceRecord = taskTop;
                    }
                } else if (r.realActivity.equals(taskTop.task.realActivity)) {
                     //...这里的代码不执行 
                } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
                     //...这里的代码不执行 
                } else if (!taskTop.task.rootWasReset) {
                     //...这里的代码不执行 
                }
                // ==================== end     
                // 此时 addingToTask为true          
                if (!addingToTask && reuseTask == null) {
                     //...这里的代码不执行 
                }
            }
        }
    } 
    //... 
    if (r.packageName != null) { 
        ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
        if (top != null && r.resultTo == null) {
            //此时task还没有B的ActivityRecord,故此不会进入下述分支
            if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                 //...这里的代码不执行
            }
        }
    } else {
           //...这里的代码不执行
    }
    boolean newTask = false;
    boolean keepCurTransition = false;
    // 此时 r.resultTo == null addingToTask为true sourceRecord != null
    if (r.resultTo == null && !addingToTask
            && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
         //...这里的代码不执行 
    } else if (sourceRecord != null) {
        if (!addingToTask &&
                (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
               //...这里的代码不执行 
        } else if (!addingToTask &&
                (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
               //...这里的代码不执行 
        }
        //将B的ActivityRecord加入A的ActivityRecord所在的Task里 
        r.setTask(sourceRecord.task, sourceRecord.thumbHolder, false);
        //... 
    } else {
         //...这里的代码不执行
    }
    //...
    startActivityLocked(r, newTask, doResume, keepCurTransition, options);
    return ActivityManager.START_SUCCESS;
}

Step1@startActivityUnCheckedLocked,前期准备

int launchFlags = intent.getFlags();

然后处理FLAG_ACTIVITY_NO_USER_ACTION.。这个标志表示并不是用户“主观意愿”启动的Activity,而是如来电,闹钟事件等触发的Activity启动。

         mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);

如果调用者指示先不要resume(doResume为空),那么我们将delayedResume设置为true。如果使用了FLAG_ACTIVITY_PREVIOUS_IS_TOP,则notTop为r本身,否则为空。

Step2@startActivityUnCheckedLocked,STRAT_FLAG_ONLY_IF_NEEDED

只在需要的情况下才启动目标,即如果被启动的对象和调用者是同一个,那么就没有必要重复操作。

Step3@startActivityUnCheckedLocked,判断是否要启动新的Task

变量launchFlags是用于记录Activity的启动方式的。如果sourceRecord为空,表明我们应该启动一个新的task来容纳目标Activity,因而需要设置FLAG_ACTIVITY_INSTANCE,或者目标ActivityRecord的(launcherMode是在AndroidManifest中设置的),也需要在新的Task中启动

Step4@startActivityUnCheckedLocked,在启动新Task的情况下无法返回结果值

如果上一步骤判断的结果是需要启动一个新的Task,那么目标Activity就和原先的调用者不在一个Task中了。由于startActivity的结果是没有办法跨越Task传递的,这时我们返回一个RESULT_CANCELED。

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
            if (resultRecord != null) {
                resultStack.sendActivityResultLocked(-1,
                    resultRecord, resultWho, requestCode,
                    Activity.RESULT_CANCELED, null);
            }
}

Step5@startActivityUnCheckedLocked. 对于新Task的细化处理

ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, this, container, options);

如果不是FLAG_ACTIVITY_INSTANCE,那么我们调用findTaskLocked 来找到符合要求的Task---此Task的最顶端就是我们要找的目标Activity一个实例。这两个函数,即findTaskLocked和finishActivityLocked都有可能返回空。

如果用户设置了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,那么执行resetTaskIfNeedLocked来清理Task。如果START_FLAG_ONLY_IF_NEEDED不为空,那么有两种可能:要么resume顶部的Activity(doResume不为空);要么abort。

如果标志FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLWAR_TASK同时存在,那么我们清理整个Task(performClearTaskLocked);否则如果FLAG_ACTIVITY_CLEAR_TOP或者launcherMode为singleTask(或singleInstance),那么就清理目标Activity以上的那些元素;否则如果Task中最顶层Activity就是目标对象,那么我们把整个Task提到前台;否则如果设置了标志FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,那么我们将目标对象加入Task顶端。

假如当前Task最顶端的Activity与我们的目标对象时同一个,那么我们需要确认整个目标是否只能启动一次。

Step6@startActivityUnCheckedLocked.接下来的代码是基于newTask为false的情况,不过也有例外。比如设置了FLAG_ACTIVITY_NEW_TASK,但是经过前面的判断后addingToTask为false,此时newTask还是为真。

Step7@startActivityUnCheckedLocked。最后调用startActivity(2)来真正的执行启动操作。这个函数不仅是AMS启动Activity的关键,同时也是Activity后续能否在WMS中得到正常处理的关键。

函数startActivity(2)是启动Activity的最后一站,主要包含以下几方面的工作。

Step1@startActivityLocked(2)。首先,如果目标Activity不是在新task中启动的,即newTask变量为false,那么程序要找出目标Activity位于哪个老Task中(这可以通过遍历整个mHistory列表来实现)。找到后,如果这个Task当前对用户还不是可见的,那么只需要将它加入mHistory,并在WMS中做好注册,但不启动它。

Step2@startActivityLocked(2)。将这个Activity放在stack的最顶层,这样才能与用户交互。

Step3@startActivityLocked(2),接下来如果不是AMS中的第一个Activity,则执行切换动画(不过这也要取决于FLAG_ACTIVITY_NO_ANIMATION标志)。执行的动画类型分为WindowManagerPolicy.TRANSIT_OPEN(如果是启动新的Task)及WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN(不启动新的Task)两种。

Step4@startActivityLocked(2),一个Activity的UI界面为了在终端屏幕上显示出来,很重要的一点就是它在WMS中必须“有档可查”,这个“档”就是appToken,它是在startActivity中添加的。

Step5@startActivityLocked(2).Activity是有affinity的----言下之意,就是它们“更亲近”与某些affinity相符的task。因而如果启动了一个新的task,就需要检查是否存在“同兴趣”的其他Activity。另外,如果用户使用了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,就满足“NEEDED”条件了,因而需要调用resetTaskIfNeededLocked。

Step6@startActivityLocked(2).调用resumeTopActivityLocked.确保被调用的Activity所在的栈处于顶端

至此,startActivity函数的一系列处理流程就分析完了---只不过Activity的启动过程还没有结束。一方面,AMS会继续调用resumeTopActivityLocked来恢复最上层的Activity,并pause之前的Activity;另一方面,在Activity切换的过程中还要首先展示切换动画,然后两个新旧Activity还会向WMS分别申请和释放Surface,最终将他们显示/不显示在屏幕上。这些内容会在WMS章节中再详细分析。

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
            Bundle targetOptions) {
        if (targetStack == null) {
            targetStack = getFocusedStack();
        }
        // Do targetStack first.
        boolean result = false;
        if (isFrontStack(targetStack)) {
            result = targetStack.resumeTopActivityLocked(target, targetOptions);
        }
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (stack == targetStack) {
                    // Already started above.
                    continue;
                }
                if (isFrontStack(stack)) {
                    stack.resumeTopActivityLocked(null);
                }
            }
        }
        return result;
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万子开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值