android launcher启动分析

/ android / 没有评论 / 1017浏览

用到的代码文件

frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/SystemService.java
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

launcher启动执行流程

下面的代码是以android N(api 24)为基础来进行流程分析。

在SystemServer中定义了main()方法,然后生成SystemServer实例并调用它的run()方法。在run()方法中启动各种各样的服务,比如ActivityManagerService(大家俗称AMS)等。而android launcher的启动就在ActivityManagerService的systemReady()方法中。下面具体的代码执行流程。

在SystemServer中:main()->run()->startOtherServices()->mActivityManagerService.systemReady()。

private ActivityManagerService mActivityManagerService;
private SystemServiceManager mSystemServiceManager;

/**
 * The main entry point from zygote.
 */
public static void main(String[] args) {
    new SystemServer().run();
}

private void run() {
    ......
    startBootstrapServices();
    startCoreServices();
    startOtherServices();
    ......
}

private void startOtherServices(){
    ......
    final NetworkManagementService networkManagementF = networkManagement;
    ......
    mActivityManagerService.systemReady(new Runnable() {
        @Override
        public void run() {
            /**
              * 让SystemServiceManager中的list mServices都启动
              */
            mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY);
            ......
            startSystemUi(context);
            ......
            if (networkManagementF != null) networkManagementF.systemReady();
            ......
            mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
            ......
        }
        ......
    }
    ......
 }

下面两个常量定义在SystemService中。在SystemService中还有很多这样的常量,这里就不一一列举了。

/**
 * After receiving this boot phase, services can broadcast Intents.
 */
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

/**
 * After receiving this boot phase, services can start/bind to third party apps.
 * Apps will be able to make Binder calls into services at this point.
 */
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

在ActivityManagerService中:systemReady()->startHomeActivityLocked()。在startHomeActivityLocked()方法中调用了一个getHomeIntent()方法,这个getHomeIntent()方法中有一句“intent.addCategory(Intent.CATEGORY_HOME);”,这样匹配到了合适的launcher apk的时候便会启动launcher了。

public void systemReady(final Runnable goingCallback) {
    ......
    startHomeActivityLocked(currentUserId, "systemReady");
    ......
}


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

/**
  * getHomeIntent获取launcher Intent
  * 下面这个方法就启动launcher
  */
boolean startHomeActivityLocked(int userId, String reason) {
    if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
            && mTopAction == null) {
        // We are running in factory test mode, but unable to find
        // the factory test app, so just sit around displaying the
        // error message and don't try to start anything.
        return false;
    }
    Intent intent = getHomeIntent();
    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
        intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
        // Don't do this if the home app is currently being
        // instrumented.
        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) {
            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;
}

这篇文章只是简单记录android launcher启动的大致流程,其中涉及到的许多细节的东西如工厂测试模式版本的判断等就不在此叙述了。 android N