SystemUI是系统应用,包括StatusBar(状态栏)、NavigationBar(导航栏),手机一开机就开始显示手机运行的状态并实时更新手机的一些运行状态。
1、先看Manifest.xml:
Service:
SystemUIService、TakeScreenshotService、KeyguardService、LoadAverageService、ImageWallpaper、DessertCaseDream、DozeService
Receiver:
BootReceiver、APChangedReceiver、RecentsUserEventProxyReceiver(最近应用相关)
TargetChosenReceiver(截屏分享)、DeleteScreenshotReceiver(删除屏幕截图通知)、TunnerService$ClearReceiver
Activity:
(1)TunerActivity、RecentsActivity、UsbStorageActivity、BrightnessDialog、Somnambulator
(2)started from UsbDeviceSettingsManager:
UsbConfirmActivity、UsbPermissionActivity、UsbAccessoryUriActivity、UsbResolverActvity
(3)started from UsbDebuggingManager:
UsbDebuggingActivity、UsbDebuggingSecondaryUserActivity
(4)started from NetworkPolicyManagerService:
NetworkOverLimitActivity
(5)started from MediaProjectionManager:
MediaProjectionPermissionActivity
(6)platform logo easter egg activity彩蛋
DessertCase、MLandActivity
SystemUIService是如何开启的?
系统服务:SystemServer.java
private void startOtherServices() {
//ActivityManagerService mActivityManagerService
mActivityManagerService.systemReady(new Runnable(){
@Override
public void run(){
try{
//启动SystemUI服务
startSystemUi(context);
}catch(Thorwable e){
reportWtf("starting System UI", e);
}
}
});
}
static final void startSystemUi(Context context){
Intent intent = new Intent();
intent.setComponent(new CompenentName("com.android.systemui","com.android.systemui.SystemUIService");
context.startServiceAsUser(intent, UserHandle.OWNER);
}
SystemService类调用startSystemUi函数启动systemuiservice,那么我们再来看看SystemUIService,它继承Service
public class SystemUIService extends Service{
FloatKeyView mFloatKeyView;
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
if (SystemProperties.get("ro.product.assistanttouch").equals("1")) {
mFloatKeyView = new FloatKeyView(this);
IntentFilter filter = new IntentFilter();
filter.addAction("com.android.systemui.FLOATKEY_ACTION_STOP");
filter.addAction("com.android.systemui.FLOATKEY_ACTION_START");
filter.addAction("com.android.systemui.FLOATKEY_ACTION_RESTART");
filter.addAction(Intent.ACTION_USER_SWITCHED);
this.registerReceiver(floatKeyReceiver, filter);
if (Settings.Secure.getInt(this.getContentResolver()
, Settings.Secure.ASSISTANT_ON, 0) != 0) {
mFloatKeyView.addToWindow();
}
// @}
}
}
@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);
}
}
}
}
private final BroadcastReceiver floatKeyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (mFloatKeyView == null)
return;
if (intent.getAction().equals(
"com.android.systemui.FLOATKEY_ACTION_STOP")) {
mFloatKeyView.removeFromWindow();
} else if (intent.getAction().equals(
"com.android.systemui.FLOATKEY_ACTION_START")) {
mFloatKeyView.addToWindow();
} else if (intent.getAction().equals(
"com.android.systemui.FLOATKEY_ACTION_RESTART")) {
mFloatKeyView.removeFromWindow();
mFloatKeyView.addToWindow();
} else if (intent.getAction().equals((Intent.ACTION_USER_SWITCHED))) {
if (Settings.Secure.getIntForUser(getContentResolver()
, Settings.Secure.ASSISTANT_ON, 0, ActivityManager.getCurrentUser()) != 0) {
mFloatKeyView.addToWindow();
} else {
mFloatKeyView.removeFromWindow();
}
}
}
};
}
onCreate方法中执行((SystemUIApplication) getApplication()).startServicesIfNeeded();
提到启动服务,且来看SystemUIApplication.java这个类
public class SystemUIApplication extends Application{
//定义了很多System Panel,这里叫做SERVICES,但是并非是真正的service.
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,
};
@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++) {
//传递开机完成的状态给每一个定义的SERVICE
mServices[i].onBootCompleted();
}
}
}
}, filter);
registerReceiver(new BroadcastReceiver(){
public void onReceive(Context context, Intent intent){
}
});
}
/**
* Makes sure that all the SystemUI services are running. If they are already running, this is a
* no-op. This is needed to conditinally start all the services, as we only need to have it in
* the main process.
*
* This method must only be called from the main thread.
*/
public void startServicesIfNeeded() {
if (mServicesStarted) {
return;
}
if (!mBootCompleted) {
// check to see if maybe it was already completed long before we began
// see ActivityManagerService.finishBooting()
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);
try {
//获得定义的SERVICE实例
mServices[i] = (SystemUI)cl.newInstance();
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
}
//初始化SERVICE
mServices[i].mContext = this;
mServices[i].mComponents = mComponents;
if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
//启动定义的SERVICE
mServices[i].start();
if (mBootCompleted) {
//告诉定义的SERVICE开机完成
mServices[i].onBootCompleted();
}
}
mServicesStarted = true;
}
}
SystemUIApplication.java这个类大概就是做了两件事:
(1)定义了一些SERVICE并启动(startServicesIfNeeded());
(2)注册广播接收者,接收开机完成的状态并将开机完成状态传递给定义的SERVICE;
这样通过SystemUIService的启动,SystemUI核心的services也启动了。SystemUI Services启动后,根据各Services的功能,SystemUI开始正常工作。