Android Framework学习(三)之Launcher

Launcher概述

Launcher程序是我们平时看到的桌面程序,它其实也是一个Android应用程序,只不过这个应用程序是系统默认第一个启动的应用程序,Android系统启动最后一步就是启动Launcher程序,应用程序Launcher在启动过程中会请求PackagerManagerService返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷键图标列表显示在系统屏幕上,这样用户可以通过点击这些快捷图标icon启动相应的应用程序。

Launcher启动流程

SystemServer进程的启动过程中会调用main静态方法,开始执行整个SystemServer的启动流程,在其中通过调用三个内部boot/core/other [Service] 在调用startOtherService方法中就会通过调用mActivityManagerService.systemReady()方法,而这个ActivityManagerServicesystemReady函数就是启动Launcher的入口。

SystemServer所有的服务启动完毕之后,在startOtherServices的最后面就开始启动startSystemUi

#startOtherServices() 
    
mActivityManagerService.systemReady(() -> {
    
    Slog.i(TAG, "Making services ready");
    t.traceBegin("StartActivityManagerReadyPhase");
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
    
    ....
        
}, t)

可以发现这个方法传递了一个 Runnable参数,里面执行了各种其他服务的systemReady方法,这里不是我们关注的重点,继续看一下在ActivityManagerServicesystemReady方法的具体实现

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

public void systemReady(final Runnable goingCallback) {
    ...
    // Start up initial activity.
    mBooting = true;
    startHomeActivityLocked(mCurrentUserId, "systemReady");
    ...
}

重点是在这个方法中调用了 startHomeActivityLocked方法,看其名字就是开始执行启动HomeActivity操作

//启动主屏幕活动:为指定用户启动主屏幕应用 参数:userId - 目标用户ID,reason - 启动原因
boolean startHomeActivityLocked(int userId, String reason) {
    if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL&& mTopAction == null) {
        //1 工厂测试检查,检查是否处于低级工厂测试模式且没有顶级动作
        return false;
    }
    Intent intent = getHomeIntent();
    //2 获取和解析主屏幕Intent
    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
        intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
        aInfo = new ActivityInfo(aInfo);
        aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
        ProcessRecord app = getProcessRecordLocked(aInfo.processName,aInfo.applicationInfo.uid, true);
        if (app == null || app.instrumentationClass == null) {
            //3 启动主屏幕
            intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
            mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
        }
    } else {
        Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
    }
    return true;
    }

mFactoryTest:代表系统运行模式,系统运行模式分为三种,分别是:

  • 非工厂模式
  • 低级工厂模式
  • 高级工厂模式

mTopActivity:描述第一个被启动的Activity组件的Action,它的值为:Intent.ACTION_MAIN ;

所以FactoryTest.FACTORY_TEST_LOW_LEVEL(低级工厂模式)并且mTopAction=null时 直接返回为 false, 执行getHomeIntent()方法

Intent getHomeIntent() {
    Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
    intent.setComponent(mTopComponent);
    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        intent.addCategory(Intent.CATEGORY_HOME);
    }
    return intent;
}

getHomeIntent函数中创建了Intent,并将mTopActionmTopData传入。

mTopAction的值为:Intent.ACTION_MAIN,并且如果系统运行模式不是低级工厂模式,则将Intent的Category设置为:Intent.CATEGORY_HOME。Launcher的Intent对象中添加了Intent.CATEGORY_HOME常量,这个其实是一个launcher的标志,一般系统的启动页面Activity都会在androimanifest.xml中配置这个标志。

在ActivityManagerService的starHomeActivityLocked函数,假设系统运行的模式不是低级工厂模式,判断符合Action为:Intent.ACTION_MAIN,Category为Intent.CATEGORY_HOME的应用程序是否已经启动,如果没启动则启动该应用程序。

创建完Launcher所需的Inten后,就判断如果Launcher没有启动的话,就会去调用 mActivityStarter.startHomeActivityLocked()去启动Launcher

//frmework/base/services/core/java/com/android/server/am/ActivityStarter.java

void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
    //讲Launcher放入HomeStack中
    mSupervisor.moveHomeStackTaskToTop(reason);
    
    //启动Launcher
    mLastHomeActivityStartResult = startActivityLocked();
    }

startHomeActivityLocked()里面,先把Launcher放入HomeStack中,HomeStack是在ActivityStackSupervisor中定义的,用来存储Launcher的变量,接着调用startActivityLocked()方法来启动Launcher。

到此,进入到LauncheronCreate方法,Launcher启动完成。

....

调用startActivityLocked()方法后面的,就涉及到Activity启动流程

核心启动时序

  1. 系统服务启动 → SystemServer 启动AMS、PMS
  2. 服务就绪 → ActivityManagerService.systemReady()
  3. HOME启动 → startHomeActivityLocked()
  4. Intent解析 → PackageManager 查找HOME应用
  5. 进程创建 → 启动Launcher进程
  6. UI初始化 → Launcher.onCreate()

关键方法调用链

  1. ActivityManagerService.systemReady()
  2. ActivityManagerService.startHomeActivityLocked()
  3. ActivityStarter.startActivity()
  4. PackageManagerService.queryIntentActivities()
  5. ActivityManagerService.startProcessLocked()
  6. Launcher.onCreate()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容