AMS之开机启动Launcher、开机广告后启动Launcher、Launcher启动activity

activity的启动关闭最终都是由AMS控制的。从刷了rom到第一开机引导、launcher启动、点击启动特定app,这之间ams控制开机引导activity、launcher、app启动有什么不同吗?还是same流程?下面让我们一探究竟。

文章分三部分:第一部总体概述、第二部分流程图、第三部分讲解下具体一些细节点。

一、总体概述:

无所做什么,一定先是了解概况,然后在看细节,不然就是只见树木不见森林。

这里就会有区分,开机广告/开机引导类似(电视现在都是先播放广告,然后启动launcher)、launcher、其他app;

本文也从这个角度进行一下分析。

简单的说,启动一个activity,先看是否已经有activity是resume状态,没有则直接启动;有则先pause掉当前resume的,然后启动想启动的;这里也不关注activity如何调用到AMS的,只关注AMS内部如何调度最终启动相关的activity的。

除了开机广告,launcher和app启动都是两个阶段:一pause当前resume的activity;二resume需要启动的activity。(先finish后pause)

牢记,就这两个阶段,不过launcher和app启动在这两个阶段有些许的区别而已。

开机广告就不多说了,后面也会给出AMS添加的方案,从AMS直接启动广告Activity播放广告,然后主动finish;系统会启动Launcher;点击相关app,启动自己想打开的应用(顺序三个阶段)

二、流程图

1.正常启动Launcher

这里先看下正常情况下的Luancher启动,即开机即启动Launcher。然后在看下先播放开机广告,然后在自动Launcher,看下异同点。


AMS被SystemServer启动之后,SystemServer会通过AMS调用startHomeActtivity启动Launcher,流程见上流程图。

其中有几个关键函数,需要关注一下:startHomeActivityLocked、startActivityLocked、addActivityToTop、resumeTopActivityLocked、realStartActivityLocked、attachApplicationLocked;几个点记住:ProcessLocked中有Process.start,最终会触发AMS的attachApplication。

从流程途中看到,起点可以算startHomeActivityLocked,终点是realStartActivityLocked

第一阶段是startHomeActivity,触发activity的进程创建;第二阶段就是AMS的attachApplication在进程创建后被调用,最终执行realStartActivityLocked会回调Activity的onCreate函数。

这里第一阶段和上面说的不太一样,不过没关系,下面看下先播开机广告在启动launcher的流程。

2.开机广告之后启动Launcher

AMS启动广告的就不看了,看下广告finish之后,Launcher启动的流程:

先看下调用栈:

第一阶段:开机广告finish掉,触发paused:
06-28 18:07:14.098  4200  4391 W System.err:    at com.android.server.am.ActivityStack.startPausingLocked(ActivityStack.java:825)
06-28 18:07:14.098  4200  4391 W System.err:    at com.android.server.am.ActivityStack.finishActivityLocked(ActivityStack.java:2745)
06-28 18:07:14.098  4200  4391 W System.err:    at com.android.server.am.ActivityStack.requestFinishActivityLocked(ActivityStack.java:2572)
06-28 18:07:14.098  4200  4391 W System.err:    at com.android.server.am.ActivityManagerService.finishActivity(ActivityManagerService.java:4543)
06-28 18:07:14.098  4200  4391 W System.err:    at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:325)
06-28 18:07:14.098  4200  4391 W System.err:    at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2267)
06-28 18:07:14.098  4200  4391 W System.err:    at android.os.Binder.execTransact(Binder.java:446)

第二阶段:paused并启动launcher
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStackSupervisor.realStartActivityLocked(ActivityStackSupervisor.java:1182)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStackSupervisor.startSpecificActivityLocked(ActivityStackSupervisor.java:1285)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:1898)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStack.resumeTopActivityLocked(ActivityStack.java:1459)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStackSupervisor.resumeTopActivitiesLocked(ActivityStackSupervisor.java:2477)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStack.startActivityLocked(ActivityStack.java:2097)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStackSupervisor.startActivityUncheckedLocked(ActivityStackSupervisor.java:2217)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:1519)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStackSupervisor.startHomeActivity(ActivityStackSupervisor.java:833)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityManagerService.startHomeActivityLocked(ActivityManagerService.java:3248)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStackSupervisor.resumeHomeStackTask(ActivityStackSupervisor.java:459)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:1504)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStack.resumeTopActivityLocked(ActivityStack.java:1459)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStackSupervisor.resumeTopActivitiesLocked(ActivityStackSupervisor.java:2477)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:998)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityStack.activityPausedLocked(ActivityStack.java:896)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:6591)
06-29 15:18:57.860  4196  4213 W System.err:    at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:512)
06-29 15:18:57.860  4196  4213 W System.err:    at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2267)
06-29 15:18:57.860  4196  4213 W System.err:    at android.os.Binder.execTransact(Binder.java:446)

流程图:


这里是开机广告播放完毕,主动调用finish();系统主动启动launcher。
这里看差别还是蛮大的。

直接启动launcher,通过进程创建,触发attach就起来了;而开机广告这种情况则复杂很多,先是finish掉开机广告,然后由pause流程触发startHomeActivity并递归调用了一次resume的流程之后才走到realStartActivityLocked,回调launcher的onCreate函数。

3.Launcher启动之后启动app

流程图:


和正常点击图标得区别不一样;主要区别是startActivity调用时机;
都有两个阶段:launcher一阶段:finish调用pause,二阶段pause调用到startHome并先调用resume之后才调用得startActivityLocked;
正常启动:一阶段:先调用startActivityLocked,并调用pause,二阶段pause调用resume直接启动activity了。
正常启动activity,会走startActivity(这里会将ActivityRecord信息加入task顶,并也调用startPausingLocked);
在后续流程中,也不同,主要是2中launcher启动递归调用了resume得几个函数;而正常启动则不会递归,
原因就是正常启动在首次就将ActivityRecord信息入task顶了,而2中launcher则没有;

三、一些注意点

1.addActivityToTop这个函数比较重要,会将要启动的activity的AcitivityRecord加入TASK顶端;这个非常重要,决定着realStartActivityLocked会不会被调用,还是启动launcher;如果执行了,即加入了Task的栈顶则这里next!=null而是相关的ActivityRecord,否则为nullfinal ActivityRecord next = topRunningActivityLocked(null);

    final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

        if (!mService.mBooting && !mService.mBooted) {
            // Not ready yet!
            return false;
        }

        // Find the first activity that is not finishing.
        final ActivityRecord next = topRunningActivityLocked(null);

        final TaskRecord prevTask = prev != null ? prev.task : null;
        if (next == null) {
            // There are no more activities!  Let's just start up the
            // Launcher...
            // Only resume home if on home display
            return isOnHomeDisplay() &&
                    mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities");
        }


2.resumeTopActivityLocked这个函数比较坑(5.1~9.0都这样),函数里有个判断会导致2.2部分的launcher启动不起来,2.2中的调用逻辑是我将AOSP代码注释掉一行以后,启动的。

看下这个函数:注意标志位:inResumeTopActivity

  final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;//注释掉即可,既能如2.2中所示调用流程,否则嵌套调用就返回,launcher无法启动
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

可以看到这个函数使用标志位inResumeTopActivity ,但是2.2中开机广告这种情况下,就会出现问题;

在2.2中,第一阶段只是进行finish处理和pause调用;第二阶段才会通过pause进行resume,但是先走到这个函数而后触发的startActivityLocked(调用addActivityToTop),随后又走到这里的时候就返回了,并没有继续执行,所以luancher就没有启动,会出现开机广告播放完成之后,一直黑屏的现象。

相关关键函数:

startHomeActivityLocked:调用启动Launcher;

startActivityLocked(ActivityStack中 ):调用触发addActivityToTop将ActivityRecord加入栈顶;

resumeTopActivityLocked:这个函数是3.1中说的函数,不修改会导致广告后launcher不启动;

realStartActivityLocked:触发app.thread.scheduleLaunchActivity,去回调mainactivity的onCreate函数;

attachApplicationLocked:由创建相关进程之后触发,此函数会触发realStartActivityLocked的调用。


总结:

整体上,这篇文章涉及较多,AMS管理task即生命周期都有涉及,如果之前没有接触过,基本看不懂,很头痛。

这里放上几篇基础文章,可以阅读后再来读本篇文章,应该会又更深刻的理解。

附上AMS关系图:

1.Android应用程序启动过程源代码分--罗升阳

2.Android系统启动流程--从SystemServer启动Launcher--百度文库

3.Android源码解析之(十五)-->Activity销毁流程--刘超

4.四大组件之ActivityRecord--GitYuan

大组件之ActivityRecord





  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Android系统在启动过程中,会依次启动各个系统服务,其中也包括Launcher服务。Launcher是Android系统的桌面显示服务,它负责管理并显示设备的主屏幕和应用程序列表。Launcher服务在Android系统的最后阶段启动,即在主界面启动之前。 当设备完成各个系统服务的启动,并且系统进入正常运行状态时,Launcher服务会被启动。系统启动时,先启动底层服务如Zygote进程、SystemServer进程等,然后再启动Android应用进程。Launcher服务作为最基本的应用程序之一,需要在其他应用程序之前加载,以确保用户可以正常使用设备的主屏幕。 Launcher服务的启动主要通过系统服务管理器来实现。系统服务管理器负责管理Android系统的各项服务,并按照事先定义好的优先级顺序启动服务。在启动Launcher服务时,系统服务管理器会调用相应的启动函数,加载Launcher相关的资源和配置文件,并开始监控用户对桌面的操作。 一旦Launcher服务启动成功,就会显示设备的主屏幕,并加载应用程序列表。通过Launcher服务,用户可以查看和管理设备上已安装的应用程序,并快捷地启动它们。同时,Launcher服务还提供了桌面小部件、壁纸等个性化设置,使用户可以自定义设备的外观和功能。 总而言之,Android系统的Launcher服务在启动过程的最后阶段启动,它管理和显示设备的主屏幕和应用程序列表,为用户提供方便的桌面操作和个性化设置。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值