Android Launcher和SystemUI的启动

一、前提提要

        Launcher即桌面程序是在系统服务等启动后打开的第一个应用程序进程,主要管理手机内部的各个用户App的展示与打开等功能,在开启Launcher的过程中SystemUI 如导航栏等布局也相继加载到屏幕中。

        Launcher的启动在各种系统服务初始化完成后进行的,即SystemServer的startOtherService()方法最后

二、启动流程

        1、SystemServer.run()

//com.android.server.SystemServer
private void run() {
    try{
        ......
        //1、创建系统Context
        createSystemContext();
        ......
    }catch(..){..}
    ......
    try{
        ......
        //2、启动其他服务
        startOtherServices(); 
        ...... 
    }catch(..){..}
    //......         
}

        系统服务如:AMS\ATMS、PMS、WMS等都是在SystemServer的run()方法中启动初始化,关于系统服务的启动不做过多介绍,这里主要有是创建了系统Context为后续启动做准备,然后进入到startOtherServices方法中

        2、startOhterServices()

//com.android.server.SystemServer
private void startOtherServices() {
    final Context context = mSystemContext;
    ......
    //wms、ims等各种服务初始化
    ......
    //通过AMS做启动前的准备
    mActivityManagerService.systemReady(() -> {
        ......
        try {
            //2、启动系统UI
            startSystemUi(context, windowManagerF);
        } catch (Throwable e) {
            reportWtf("starting System UI", e);
        }
        ......
    },BOOT_TIMINGS_TRACE_LOG);
}

        在startOtherServices方法中先是完成必要的系统服务后,通过AMS开始对Launcher的启动进行准备工作,调用AMS的systemReady方法传入了一个Callback,并且在Callback中又对系统UI进行启动

        3、启动SystemUI

//com.android.server.SystemServer
private static void startSystemUi(Context context, WindowManagerService windowManager) {
    //启动系统UI Service
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.android.systemui",
            "com.android.systemui.SystemUIService"));
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    //Slog.d(TAG, "Starting service: " + intent);
    context.startServiceAsUser(intent, UserHandle.SYSTEM);
    windowManager.onSystemUiStarted();
}

        通过启动Service的方式初始化UI

//com.android.systemui.SystemUIService
public class SystemUIService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        //执行SystemUIApplication中的创建方法
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
        ......
    }
    ......
}

          在Service的onCreate()方法中又调用了当前Application的startServicesIfNeeded方法继续初始化

        在前面的createSystemContext()方法中创建了Context的同时也创建的Application对象,Application的具体实例类型是通过解析对应的AndroidManifest.xml获取,此处创建的Application所解析的xml在 /frameworks/base/packages/SystemUI 包下

//frameworks/base/packages/SystemUI/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     package="com.android.systemui"
     android:sharedUserId="android.uid.systemui"       
     coreApp="true">
     ......
      <application
          //Application类
          android:name=".SystemUIApplication"       
          android:persistent="true"    
          android:allowClearUserData="false"
          android:allowBackup="false"
          .....
      </application>
</manifest>
          

        SystemUIApplication中继续执行

//com.android.systemui.SystemUIApplication
public void startServicesIfNeeded() {
    //获取需要初始化系统UI的名字
    String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
    startServicesIfNeeded(names);
}

private void startServicesIfNeeded(String[] services) {
    if (mServicesStarted) {
        return;
    }
    //SystemUI集合,系统UI都继承自SystemUI
    mServices = new SystemUI[services.length];
    ......
    final int N = services.length;
    for (int i = 0; i < N; i++) {
        String clsName = services[i];
        ......
        Class cls;
        try {
            //通过反射实例化各个系统UI
            cls = Class.forName(clsName);
            Object o = cls.newInstance();
            if (o instanceof SystemUI.Injector) {
                o = ((SystemUI.Injector) o).apply(this);
            }
            mServices[i] = (SystemUI) o;
        } ......

        mServices[i].mContext = this;
        mServices[i].mComponents = mComponents;
        if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
        //初始化系统UI (4-1)
        mServices[i].start();
        ......
        if (mBootCompleted) {
            mServices[i].onBootCompleted();
        }
    }
    .......
}

        从config.xml获取需要初始化的各个SystemUI类名,然后创建SystemUI数组并遍历集合通过反射的方式创建实例,最后调用SystemUI.start()方法对每个SystemUI初始化和渲染

        config_systemUIServiceComponents定义在在/frameworks/base/packages/SystemUI/res/values/config.xml 文件下,其中包括了 如 顶部状态栏、通知、键盘等一些列UI

<!-- SystemUI Services: The classes of the stuff to start. -->    
<string-array name="config_systemUIServiceComponents" translatable="false">       
    <item>com.android.systemui.Dependency</item>
    <item>com.android.systemui.util.NotificationChannels</item>
    <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>        
    <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
    <item>com.android.systemui.recents.Recents</item>
    <item>com.android.systemui.volume.VolumeUI</item>
    <item>com.android.systemui.stackdivider.Divider</item>
    <item>com.android.systemui.SystemBars</item> 
    <item>com.android.systemui.usb.StorageNotification</item>
    <item>com.android.systemui.power.PowerUI</item>
    <item>com.android.systemui.media.RingtonePlayer</item>
    <item>com.android.systemui.keyboard.KeyboardUI</item>
    <item>com.android.systemui.pip.PipUI</item> 
    <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
    <item>@string/config_systemUIVendorServiceComponent</item>
    <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
    <item>com.android.systemui.LatencyTester</item>
    <item>com.android.systemui.globalactions.GlobalActionsComponent</item> 
    <item>com.android.systemui.ScreenDecorations</item>
    <item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
    <item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>

        

        以SystemBars为例:

//继承自SystemUI
public class SystemBars extends SystemUI {
    ......
    //执行的start()方法
    @Override
    public void start() {
        if (DEBUG) Log.d(TAG, "start");
        //创建StatusBar
        createStatusBarFromConfig();
    }
    ......
    private void createStatusBarFromConfig() {
        if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
        //获取StatusBar类名
        //com.android.systemui.statusbar.phone.StatusBar
        final String clsName = mContext.getString(R.string.config_statusBarComponent);
        if (clsName == null || clsName.length() == 0) {
            throw andLog("No status bar component configured", null);
        }
        Class<?> cls = null;
        try {
            cls = mContext.getClassLoader().loadClass(clsName);
        } catch (Throwable t) {
            throw andLog("Error loading status bar component: " + clsName, t);
        }
        try {
            //通过反射创建StatusBar对象
            mStatusBar = (SystemUI) cls.newInstance();
        } catch (Throwable t) {
            throw andLog("Error creating status bar component: " + clsName, t);
        }
        mStatusBar.mContext = mContext;
        mStatusBar.mComponents = mComponents;
        if (mStatusBar instanceof StatusBar) {
            SystemUIFactory.getInstance().getRootComponent()
                .getStatusBarInjector()
                .createStatusBar((StatusBar) mStatusBar);
        }
        //StatusBar也是继承SystemUI继续执行start方法
        mStatusBar.start();
        if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
    }
    ......
}

        SystemBar的start()中创建了StatusBar对象,StatusBar也是继承自SystemUI,再次执行start()方法

//com.android.systemui.statusbar.phone.StatusBar

//继承SystemUI
public class StatusBar extends SystemUI implements ...{
    ......
    @Override
    public void start() {
        ......
        //获取WMS
        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        ......  
        mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
        ......
        //创建并将view添加到屏幕
        createAndAddWindows(result);
        ......
    }
    ......
    
    public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
        //创建StatusView
        makeStatusBarView(result);
        mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
        //添加到Window 涉及到WMS绘制
        mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());
    }
 }

        可以看到StatusBar中实际创建了View,并通过WMS绘制到屏幕中

        4、启动Launcher

        继续回到SystemServer代码

//com.android.server.SystemServer
private void startOtherServices() {
    ......
    //通过AMS做启动前的准备
    mActivityManagerService.systemReady(() -> {
        ......
        try {
            //2、启动系统UI
            startSystemUi(context, windowManagerF);
        } catch (Throwable e) {
            reportWtf("starting System UI", e);
        }
        ......
    },BOOT_TIMINGS_TRACE_LOG);
}

        进入到AMS.systemReady()方法

//com.android.server.am.ActivityManagerService.java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    synchronized(this) {
        if (mSystemReady) {
            // 如果初始化过一次 那就直接执行callback
            if (goingCallback != null) {
                goingCallback.run();
            }
            return;
        }

        mLocalDeviceIdleController
            = LocalServices.getService(DeviceIdleController.LocalService.class);
        //准备完成配置信息
        mActivityTaskManager.onSystemReady();
        mUserController.onSystemReady();
        mAppOpsService.systemReady();
        mSystemReady = true;
    }
    ......
    //执行callback 初始化系统UI等操作
    if (goingCallback != null) goingCallback.run();
    ......
    synchronized (this) {
        ......
        //启动Launcher
        mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); 
        ......  
    }
}

        在内部做了防止多次初始化启动的操作,配置完各项信息调用ActivityTaskManagerInternal的startHomeOnAllDisplays启动Launcher

        这里简单了解一下mAtmInternal的创建过程

        1、mAtmInternal是ActivityTaskManagerInternal类型,管理AtivityTaskManager

功能的接口。它的获取是在ActivityManagerService构造方法中

public ActivityManagerService(Context systemContext, 
        ActivityTaskManagerService atm) {
    ......
    //通过ATMI.class获取具体实现类
    mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
    ......
}

        LocalServices内部维护一个Map,主要用来存取本地的一些接口服务此处获取ActivityTaskManagerInternal的实现类

        2、ActivityTaskManagerInternal是一个接口具体实现类是ActivityTaskManagerService

内部的LocalService

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    ......
    final class LocalService extends ActivityTaskManagerInternal {
        ......
    }
    ......
}

        

        3、LocalService的创建是在ATMS的构造函数中,而添加到LocalServices是在ATMS

服务启动的时候

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    ......
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public ActivityTaskManagerService(Context context) {
        ......   
        mInternal = new LocalService();
        ......
    }
    ......
    //ATMS启动
    private void start() {
        //添加到LocalServices,key为ATMI.class
        LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
    }
}

        ATMS的启动则是在SystemServer中进行的,这里就不多做赘述

        继续回到mAtmInternal.startHomeOnAllDisplays方法

final class LocalService extends ActivityTaskManagerInternal {
    ......
    @Override
    public boolean startHomeOnAllDisplays(int userId, String reason) {
        synchronized (mGlobalLock) {
            //继续执行RootWindowContainer的方法
            return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
        }
    }
    ......
}

        RootWindowContainer.startHomeOnAllDisplays

class RootActivityContainer extends ConfigurationContainer
        implements DisplayManager.DisplayListener {
    ......
    boolean startHomeOnAllDisplays(int userId, String reason) {
        boolean homeStarted = false;
        for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
            final int displayId = mActivityDisplays.get(i).mDisplayId;
            //1、获取并继续调用启动方法
            homeStarted |= startHomeOnDisplay(userId, reason, displayId);
        }
        return homeStarted;
    }
    ......
    
    boolean startHomeOnDisplay(int userId, String reason, int displayId) {
        //2、
        return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
            false /* fromHomeKey */);
    }
    
    boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
        boolean fromHomeKey) {
        // Fallback to top focused display or default display if the displayId is invalid.
        if (displayId == INVALID_DISPLAY) {
            final ActivityStack stack = getTopDisplayFocusedStack();
            displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY;
        }

        final DisplayContent display = getDisplayContent(displayId);
        boolean result = false;
        for (int tcNdx = display.getTaskDisplayAreaCount() - 1; tcNdx >= 0; --tcNdx) {
            final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tcNdx);
            result |= startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
                allowInstrumenting, fromHomeKey);
        }
        return result;
    }
    
    boolean startHomeOnTaskDisplayArea(int userId, String reason, int displayId, boolean allowInstrumenting,
        boolean fromHomeKey) {
        ......
        //Launcher的Intent
        Intent homeIntent = null;
        ActivityInfo aInfo = null;
        //3、获取Launcher的Activity信息
        if (taskDisplayArea == getDefaultTaskDisplayArea()) {
            homeIntent = mService.getHomeIntent();
            aInfo = resolveHomeActivity(userId, homeIntent);
        } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
            Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
            aInfo = info.first;
            homeIntent = info.second;
        }
        ......
        //检测是否允许启动
        //内部有对系统运行模式和TopAction以及分屏的判断
        if (!canStartHomeOnDisplayArea(aInfo, displayId, allowInstrumenting)) {
            return false;
        }

        //更新Launcher的启动信息
        homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
        homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
        // Updates the extra information of the intent.
        if (fromHomeKey) {
            homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
        }
        // Update the reason for ANR debugging to verify if the user activity is the one that
        // actually launched.
        final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
            aInfo.applicationInfo.uid) + ":" + displayId;
        //4、启动Launcher Activity
        mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
            displayId);
        return true;
    }
}

       最后通过ATMS获取ActivityStartController对象,并调用startHomeActivity启动了Launcher。

后续启动流程与点击App应用冷启动过程类似,等整理完成后再出下一篇博客

三、最后

        本文通过自己对Android 10版本源码的理解整理发布,其中很多细节不够详细还需要进一步理解,如果出现错误欢迎指正,如果小伙伴有更好的流程解析欢迎一起探讨

### Android SystemUI Launcher 启动顺序详解 在Android系统的启动过程中,System UILauncher的初始化遵循特定的流程。 #### 1. 系统引导完成后的初始阶段 当设备完成硬件自检并加载内核后,init进程会解析`/init.rc`文件来启动Zygote进程。Zygote作为Android应用程序的孵化器,在其准备好之后,会通过Socket监听来自AMS的创建请求[^2]。 #### 2. ActivityManagerService (AMS) 的角色 一旦Zygote准备就绪,AMS将被通知,并由后者发起一系列核心组件服务的启动操作。这其中包括但不限于Home应用(即Launcher)以及其他必要的系统级服务。 #### 3. SystemServer 进程中的关键步骤 - **启动System Server**: Zygote孵化出的第一个子进程就是System Server, 它承载着众多重要框架层的服务实例化工作。 - **注册Intent Filters**: 在此期间,各个预定义的应用程序组件向AMS注册它们所支持的动作意图过滤器。对于Launcher而言,则是声明了如下配置项: ```xml <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.HOME"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> ``` - **设置默认HOME activity**: AMS依据这些已注册的信息判断哪个Activity应该成为当前用户的桌面环境入口,默认情况下会选择具有上述指定属性组合的那个选项[^1]。 #### 4. System UI 组件激活 与此同时,System UI也在同一进程中被执行起来,负责提供状态栏、导航栏等功能界面给用户交互使用。由于这部分属于系统底层的一部分,因此通常会在其他第三方APP之前显示出来。 综上所述,在正常开机状态下,先是System UI呈现基本视觉反馈;紧接着,AMS选定合适的Launcher作为home screen展示给最终使用者。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值