Android SystemUI组件(01)SystemUIService启动

112 篇文章 88 订阅

该系列文章总纲链接:专题分纲目录 Android SystemUI组件


本章关键点总结 & 说明:

说明:本章节主要涉及SystemUI的两个启动过程,开机启动和服务启动,最终是启动SystemUI子类的各个服务。

1 SystemUIService开机启动流程

SystemUI是Android系统级的UI组件。在开机启动后,SystemServer启动中 ,开始执行对应的run方法,代码实现如下:

private void run() {
    //...
    // Start services.
    try {
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    }
    //...
}

在run方法中,执行了startOtherServices,当SystemServer中核心系统服务启动完成后会调用AMS的systemReady()方法通知AMS系统已经就绪。代码实现如下:

private void startOtherServices() {
        //...
        StatusBarManagerService statusBar = null;
        INotificationManager notification = null;
        //...
        mActivityManagerService.systemReady(new Runnable() {
            @Override
            public void run() {
                Slog.i(TAG, "Making services ready");
                mSystemServiceManager.startBootPhase(
                        SystemService.PHASE_ACTIVITY_MANAGER_READY);

                try {
                    mActivityManagerService.startObservingNativeCrashes();
                } catch (Throwable e) {
                    reportWtf("observing native crashes", e);
                }

                Slog.i(TAG, "WebViewFactory preparation");
                WebViewFactory.prepareWebViewInSystemServer();

                try {
                    startSystemUi(context);
                } catch (Throwable e) {
                    reportWtf("starting System UI", e);
                }
                //...
            }
}

在SystemServer中startSystemUi的代码实现如下:

static final void startSystemUi(Context context) {
    Intent intent = new Intent();
    //设置SystemUIService作为启动目标
    intent.setComponent(new ComponentName("com.android.systemui",
                "com.android.systemui.SystemUIService"));
    //启动SystemUIService
    context.startServiceAsUser(intent, UserHandle.OWNER);
}

这里通过 context的startServiceAsUser方法进行SystemUIService的启动,至此SystemUIService服务的开机启动流程就完成了。

2 SystemUIService服务启动

SystemUIService代码并不多,代码如下:

public class SystemUIService extends Service {
    //关键方法
    @Override
    public void onCreate() {
        super.onCreate();
        //从这里可以看出,分析SystemUIApplication的startServicesIfNeeded实现即可
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        SystemUI[] services = ((SystemUIApplication) getApplication()).getServices();
        if (args == null || args.length == 0) {
            for (SystemUI ui: services) {
                pw.println("dumping service: " + ui.getClass().getName());
                ui.dump(fd, pw, args);
            }
        } else {
            String svc = args[0];
            for (SystemUI ui: services) {
                String name = ui.getClass().getName();
                if (name.endsWith(svc)) {
                    ui.dump(fd, pw, args);
                }
            }
        }
    }
}

这里主要分析SystemUIService的onCreate()中startServicesIfNeeded的实现,也就是类SystemUIApplication中 startServicesIfNeeded的代码,如下所示:

public class SystemUIApplication extends Application {
	//...
	//成员变量SERVICES存储了各个服务的实例,数组内容如下:
	private final Class<?>[] SERVICES = new Class[] {
		com.android.systemui.keyguard.KeyguardViewMediator.class,
		com.android.systemui.recent.Recents.class,
		com.android.systemui.volume.VolumeUI.class,
		com.android.systemui.statusbar.SystemBars.class,
		com.android.systemui.usb.StorageNotification.class,
		com.android.systemui.power.PowerUI.class,
		com.android.systemui.media.RingtonePlayer.class
	};
	//...
	private final SystemUI[] mServices = new SystemUI[SERVICES.length];
	//...
	public void startServicesIfNeeded() {
        //如果SystemUI已经启动过了则不需要再启动
		if (mServicesStarted) {
			return;
		}

		if (!mBootCompleted) {
			if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
				mBootCompleted = true;
			}
		}

		final int N = SERVICES.length;
		for (int i=0; i<N; i++) {
			Class<?> cl = SERVICES[i];
			//...
			//实例化子服务并将其存储在mServices数组中
			mServices[i] = (SystemUI)cl.newInstance();
			//...
			//设置context,并调用start方法启动该类型的服务。
			mServices[i].mContext = this;
			mServices[i].mComponents = mComponents;
			mServices[i].start();

			if (mBootCompleted) {
				mServices[i].onBootCompleted();
			}
		}
		mServicesStarted = true;
	}
    //...
}

由上可见,SystemUIService是一个容器。主要为了启动以下服务:

  • com.android.systemui.keyguard.KeyguardViewMediator,锁屏管理
  • com.android.systemui.recent.Recents,近期应用管理
  • com.android.systemui.volume.VolumeUI,显示和控制音量的变化:媒体、铃声、闹钟音量
  • com.android.systemui.statusbar.SystemBars,系统 状态栏
  • com.android.systemui.usb.StorageNotification,系统 通知栏
  • com.android.systemui.power.PowerUI,电池模式切换
  • com.android.systemui.media.RingtonePlayer,铃声播放

这些服务类有一个共同特点,均继承于SystemUI抽象类,如下:

public class KeyguardViewMediator extends SystemUI {...}
public class Recents extends SystemUI implements RecentsComponent {...}
public class VolumeUI extends SystemUI {...}
public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks {...}
public class StorageNotification extends SystemUI {...}
public class PowerUI extends SystemUI {...}
public class RingtonePlayer extends SystemUI {...}

SystemUI抽象类的内部实现如下所示:

public abstract class SystemUI {
    public Context mContext;
    public Map<Class<?>, Object> mComponents;

    public abstract void start();

    protected void onConfigurationChanged(Configuration newConfig) {
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    }

    protected void onBootCompleted() {
    }

    @SuppressWarnings("unchecked")
    public <T> T getComponent(Class<T> interfaceType) {
        return (T) (mComponents != null ? mComponents.get(interfaceType) : null);
    }
    public <T, C extends T> void putComponent(Class<T> interfaceType, C component) {
        if (mComponents != null) {
            mComponents.put(interfaceType, component);
        }
    }
}

可以看到最关键的是start方法,因此分析抽象类SystemUI的几个实现类均从start开始即可。接下来的章节我们 分别从这些子类的start方法开始分析。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图王大胜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值