Android之SystemUI加载流程和NavigationBar的分析
Android之SystemUI加载流程和NavigationBar的分析
本篇只分析SystemUI的加载过程和SystemUI的其中的一个模块StatusBar的小模块NavigationBar,以Android6.0代码进行分析
AndroidManifest.xml
SystemUIService
跟StatusBar相关的服务为SystemUIService
,我们查看SystemUIService
源码
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
//获取Application调用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
代码,可以知道SystemUI主要做了两件事
Application
对象加载SystemUI相关的类,这个等下分析SystemUIApplication
代码可以知道 dump
打印SystenUISerice
运行过程中相关的堆栈信息
那么SystemUIService
又是哪里开始启动的呢?竟然SystemUIService是个服务,那么启动服务要么就是startService
要么就是bindService进行启动,其启动方式则需要通过Intent来传入类名或者包名,因此在源码中搜索SystemUIService可以对比发现,它在
frameworks\base\services\java\com\android\server\SystemServer.java中进行启动
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.OWNER);
}
在SystemServer的run方法中startOtherServices来启动SystemUIService服务,至于SystemServer则涉及到Android的启动流程,其大概流程为
int -> ServerManager -> Zygote -> SystemServer
SystemServer中会初始化一些Android的java层的服务,如ActivityManagerService、WindowManagerService等
这里SystemUI的加载过程就到此告一段落了,下面分析StatusBar的加载流程
上面讲到在SystemUIService的onCreate中获取SystemUIApplication对象来初始化SystemUI相关的类,这些类里面就包括了StatusBar相关的类,我们查看SystemUIApplication类
SystemUIApplication
onCreate
@Override
public void onCreate() {
super.onCreate();
// Set the application theme that is inherited by all services. Note that setting the
// application theme in the manifest does only work for activities. Keep this in sync with
// the theme set there.
setTheme(R.style.systemui_theme);
//注释广播
IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//开启直接返回
if (mBootCompleted) return;
if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received");
unregisterReceiver(this);
//标记启动
mBootCompleted = true;
//服务是否启动
if (mServicesStarted) {
final int N = mServices.length;
for (int i = 0; i < N; i++) {
//回调各服务的onBootCompleted函数
mServices[i].onBootCompleted();
}
}
}
}, filter);
}
在SystemUIApplication的onCreate中主要做了
设置主题(这个会影响其SystemUI的界面显示效果) 注册开机广播,设置标志位startServicesIfNeeded
SystemUIService中的onCreate启动了这个方法,我们着重分析这个方法
public void startServicesIfNeeded() {
if (mServicesStarted) {
return;
}
if (!mBootCompleted) {
// check to see if maybe it was already completed long before we began
// see ActivityManagerService.finishBooting()
//获取系统文件中的sys.boot_completed的值
if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
mBootCompleted = true;
if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
}
}
Log.v(TAG, "Starting SystemUI services.");
final int N = SERVICES.length;
for (int i=0; i cl = SERVICES[i];
if (DEBUG) Log.d(TAG, "loading: " + cl);
//实例化各个类实例,放入mServices数组中
try {
mServices[i] = (SystemUI)cl.newInstance();
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
mServices[i].mComponents = mComponents;
if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
mServices[i].start();
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
//服务启动标志
mServicesStarted = true;
}
这个方法中,首先判断mServicesStarted
标志为来判断SystemUI相关的服务是否启动,同时根据系统配置文件来检查ActivityManagerService是否finishBooting,然后通过类加载机制来初始化SERVICES数组里面相关的类加入mServices中,然后start
/**
* The classes of the stuff to start.
*/
private final Class[] SERVICES = new Class[] {
com.android.systemui.tuner.TunerService.class,//定制状态栏服务
com.android.systemui.keyguard.KeyguardViewMediator.class,//锁屏相关
com.android.systemui.recents.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,//铃声播放相关
};
/**
* Hold a reference on the stuff we start.
*/
private final SystemUI[] mServices = new SystemUI[SERVICES.length];
从mServices和SERVICES的定义可以发现SERVICES是一组包含全路径的相关的类,这些类包含一些我们常见的TunerService(定制状态栏服务)、
KeyguardViewMediator(锁屏相关)、Recents(近期任务)、VolumeUI(音量条)、SystemBars(状态栏)、StorageNotification(通知栏)、