Android 9.0系统源码_SystemUI(一)SystemUI的启动流程

一、SystemUI 介绍

1、初步认识SystemUI
Android 的 SystemUI 其实就是 Android 的系统界面,它包括了界面上方的状态栏 status bar,下方的导航栏Navigation Bar,锁屏界面 Keyguard ,电源界面 PowerUI,近期任务界面 Recent Task 等等。对于用户而言,SystemUI 的改动是最能直观感受到的。因此,每个 Android 版本在 SystemUI 上都有比较大的改动。而对开发者而言,理解 Android SystemUI 对优化Android系统界面,改善用户体验十分重要。

2、SystemUI 在哪
在 Andorid 系统源码中,package/apps下放的是系统内置的一些 app,例如 settings,camera,Phone,Message 等等。而在 framework/base/package 下,它们也是系统的 app,SystemUI 就在此目录下。它控制着整个Android系统的界面,但其实他也是一个 app,不同于一般的 app,它不可卸载也不可以被第三方应用替换。因为SystemUI 是系统应用,所以它也是一个 APK,有入口 Application,只不过它是由 SystemServer 进程进行启动的。

3、SystemUI 整体结构
在这里插入图片描述
这是 SystemUI 相关类的继承关系图,可以看到 SystemUI 为基类,每个子类实现了不同的系统界面。

Status Bar 系统上方的状态栏
Navigator Bar 系统下方的导航栏
Keyguard 锁屏界面
PowerUI 电源界面
Recents Screen 近期任务界面
VolumeUI 音量调节对话框
Stack Divider 分屏功能调节器
PipUI 画中画界面
Screenshot 截屏界面
RingtonePlayer 铃声播放器界面
Settings Activity 系统设置中用到的一些界面,例如:NetworkOverLimitActivity,UsbDebuggingActivity等。
在这里插入图片描述

二、系统启动后在SystemServer进程中启动SystemUIService

1、SystemServer进程里面有个main()方法,main 方法如下:

framework/base/service/java/com/android/server/SystemServer.java

    public static void main(String[] args) {
        new SystemServer().run();
    }

2、main 方法里启动了 run() 方法,而在 run 方法中调用了startOtherServices() 方法:

   private void run() {
    	...
    	// Start services.
        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();//启动引导服务
            startCoreServices();//启动核心服务
            startOtherServices();//启动其他服务
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
    	...
    }

3、在 startOtherServices() 里 mActivityManagerService.systemReady 创建线程去执行startSystemUi(context),这里将启动SystemUI。具体方法如下:

    private void startOtherServices() {
            mActivityManagerService.systemReady(() -> {
          		...
	          	try {
	                startSystemUi(context, windowManagerF);
	            } catch (Throwable e) {
	                reportWtf("starting System UI", e);
	            }
          		...  
          }
    }
    //启动SystemUI
    static final void startSystemUi(Context context, WindowManagerService windowManager) {
        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();
    }

三、在 SystemUIService 中启动 SystemUI 所需的各种组件

1、然后我们进入设置启动 systemui 程序的 SystemUIService 文件里,该类的onCreate() 方法如下:

framework/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java.

public class SystemUIService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
    }
  }

2、((SystemUIApplication) getApplication()).startServicesIfNeeded()这句很关键,该方法如下:

framework/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java

    public void startServicesIfNeeded() {
        String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
        startServicesIfNeeded(names);
    }

3、SystemUI要启动的所有组件都是在数组 config_systemUIServiceComponents中定义的,可以看下这个数组的定义:

frameworks/base/packages/SystemUI/res/values/config.xml

  <!-- 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>

4、继续看SystemUIApplication的startServicesIfNeeded(String[] services)方法,其中有一个 for 循环,循环里第一句就是将 service[i] 赋值给 clsName, 而service[i]的赋值就是各个SystemUI组件的具体类对象路径,这里通过反射的方法,创建出来对应的SystemUI组件实例对象:

    private void startServicesIfNeeded(String[] services) {
 		...
        mServices = new SystemUI[services.length];
        ...
        final int N = services.length;
        for (int i = 0; i < N; i++) {
            String clsName = services[i];//具体系统组件类的完整路径
            if (DEBUG) Log.d(TAG, "loading: " + clsName);
            log.traceBegin("StartServices" + clsName);
            long ti = System.currentTimeMillis();
            Class cls;
            try {
                cls = Class.forName(clsName);
                mServices[i] = (SystemUI) cls.newInstance();//通过反射创建实例对象
            } catch(ClassNotFoundException ex){
                throw new RuntimeException(ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
            }

            mServices[i].mContext = this;
            mServices[i].mComponents = mComponents;
            ...
            mServices[i].start();
   			...
            ti = System.currentTimeMillis() - ti;
			...
            if (mBootCompleted) {
                mServices[i].onBootCompleted();
            }
        }
		...
        mServicesStarted = true;
    }

看到这里我们应该就明白了,这里是拿到每个和 SystemUI 组件相关的类的完整路径,存到了service[] 里,然后赋值给cls,紧接着通过反射将其转化为具体的类对象,存到了mService[i]数组里,最后对象调start() 方法启动相关类的服务,启动完成后,再调用该类的onBootCompleted( ) 方法。

至此我们已经分析完了SystemUI的启动流程,后续篇章我们将会继续通过源码来分析系统状态栏、导航栏等各种常见的SystemUI组件的启动流程。
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
根据提供的引用内容,我们可以了解到Android 9.0系统源码中SwipeHelper.java的位置为frameworks/base/packages/SystemUI/src/com/android/systemui/SwipeHelper.java。SwipeHelper.java是一个帮助类,用于处理滑动手势的事件。下面是SwipeHelper.java源码分析的流程: 1.首先,我们需要了解SwipeHelper.java的作用和功能。SwipeHelper.java是一个帮助类,用于处理滑动手势的事件。它可以检测用户的手势方向,并根据手势方向执行相应的操作。 2.接下来,我们需要了解SwipeHelper.java的主要方法和变量。SwipeHelper.java包含了一些重要的方法和变量,例如: - mSwipeDirection:表示滑动的方向,可以是上、下、左、右等方向。 - mSwipeThreshold:表示滑动的阈值,当用户滑动的距离超过这个阈值时,才会触发滑动事件。 - onInterceptTouchEvent:用于拦截触摸事件,判断是否需要处理滑动事件。 - onTouchEvent:用于处理触摸事件,根据手势方向执行相应的操作。 3.然后,我们需要了解SwipeHelper.java的具体实现。SwipeHelper.java主要实现了以下几个方法: - onInterceptTouchEvent:该方法用于拦截触摸事件,判断是否需要处理滑动事件。在该方法中,SwipeHelper会根据触摸事件的类型和位置,判断是否需要处理滑动事件。如果需要处理滑动事件,则返回true,否则返回false。 - onTouchEvent:该方法用于处理触摸事件,根据手势方向执行相应的操作。在该方法中,SwipeHelper会根据触摸事件的类型和位置,判断用户的手势方向,并根据手势方向执行相应的操作。例如,如果用户向左滑动,则会执行onSwipeLeft方法。 - onSwipeLeft:该方法用于处理向左滑动事件。在该方法中,SwipeHelper会执行一些操作,例如关闭通知栏、打开侧边栏等。 - onSwipeRight:该方法用于处理向右滑动事件。在该方法中,SwipeHelper会执行一些操作,例如打开通知栏、关闭侧边栏等。 - onSwipeUp:该方法用于处理向上滑动事件。在该方法中,SwipeHelper会执行一些操作,例如打开最近任务列表、打开应用程序列表等。 - onSwipeDown:该方法用于处理向下滑动事件。在该方法中,SwipeHelper会执行一些操作,例如关闭最近任务列表、关闭应用程序列表等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值