init -> ServerManager -> Zygote -> SystemServer -> SystemUIService ->
SystemUIApplication SystemServer启动后,会在SystemServer Main
Thread启动ActivityManagerService,当ActivityManagerService
systemReady后,会去启动SystemUIService。可以看出,startSystemUi不是在SystemServer
Main thread,而是在ActivityManagerService Thread。
\frameworks\base\services\java\com\android\server\SystemServer.java
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored
* and organized.
*/
private void startOtherServices() {
if (!disableSystemUI) {
try {
Slog.i(TAG, "Status Bar");
statusBar = new StatusBarManagerService(context, wm);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
} catch (Throwable e) {
reportWtf("starting StatusBarManagerService", e);
}
}
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
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);
}
备注:
context.startServiceAsUser(…)调用的是\frameworks\base\core\java\android\app\ContextImpl.java中的startServiceAsUser(…),而startServiceAsUser(…)调用startServiceCommon(…)
SystemServer在startSystemUi启动SystemUIService后,会走到SystemUIService的onCreate函数。
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
} /* 这个SystemUIService很短,代码不到60行 */
可见SystemUIService调用了SystemUIApplication的startServicesIfNeeded()。
\frameworks\base\packages\SystemUI\src\com\android\systemui\ SystemUIApplication.java
/**
* Application class for SystemUI.
*/
public class SystemUIApplication extends Application {
private static final String TAG = "SystemUIService";
private static final boolean DEBUG = false;
/**
* The classes of the stuff to start.
*/
private final Class<?>[] SERVICES = new Class[] {
com.android.systemui.keyguard.KeyguardViewMediator.class, // 锁屏机制
com.android.systemui.recent.Recents.class, // 近期任务
com.android.systemui.volume.VolumeUI.class, // 音量UI
com.android.systemui.statusbar.SystemBars.class, // 系统栏
com.android.systemui.usb.StorageNotification.class, // 存储信息通知
com.android.systemui.power.PowerUI.class, // 电源UI
com.android.systemui.media.RingtonePlayer.class // 铃声播放
}; // 它们并不是真正的Service ,继承了SystemUI.java这个抽象类,复写了start()方法
/**
* Hold a reference on the stuff we start.
*/
private final SystemUI[] mServices = new SystemUI[SERVICES.length];
private boolean mServicesStarted;
private boolean mBootCompleted;
private final Map<Class<?>, Object> mComponents = new HashMap<Class<?>, Object>();
@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++) {
mServices[i].onBootCompleted();
}
}
}
}, filter);
}
/**
* 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.
*
* <p>This method must only be called from the main thread.</p>
*/
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循环逐个启动SystemUI的各个服务(电源UI、音量UI、状态栏等)
for (int i=0; i<N; i++) {
Class<?> cl = SERVICES[i];
if (DEBUG) Log.d(TAG, "loading: " + cl);
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(); // 调用各个”服务”的start()方法
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
mServicesStarted = true;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (mServicesStarted) {
int len = mServices.length;
for (int i = 0; i < len; i++) {
mServices[i].onConfigurationChanged(newConfig);
}
}
}
@SuppressWarnings("unchecked")
public <T> T getComponent(Class<T> interfaceType) {
return (T) mComponents.get(interfaceType);
}
// 暴露的接口
public SystemUI[] getServices() {
return mServices;
}
}
下面看SystemBars.java的start()方法
@Override
public void start() {
if (DEBUG) Log.d(TAG, "start");
mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
mServiceMonitor.start(); // will call onNoService if no remote service is found
}
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\ServiceMonitor.java
public ServiceMonitor(String ownerTag, boolean debug,
Context context, String settingKey, Callbacks callbacks) {
mTag = ownerTag + ".ServiceMonitor";
mDebug = debug;
mContext = context;
mSettingKey = settingKey;
mCallbacks = callbacks;
}
public void start() {
// listen for setting changes
ContentResolver cr = mContext.getContentResolver();
cr.registerContentObserver(Settings.Secure.getUriFor(mSettingKey),
false /*notifyForDescendents*/, mSettingObserver, UserHandle.USER_ALL);
// listen for package/component changes
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
mContext.registerReceiver(mBroadcastReceiver, filter);
mHandler.sendEmptyMessage(MSG_START_SERVICE);
}
init -> ServerManager -> Zygote -> SystemServer -> SystemUIService -> SystemUIApplication
状态栏启动:
SystemUIApplication -> SystemBars
SystemBars里面createStatusBarFromConfig() {
……
String clsName = mContext.getString(R.string.config_statusBarComponent);
……
cls = mContext.getClassLoader().loadClass(clsName);
……
mStatusBar = (BaseStatusBar) cls.newInstance();
……
mStatusBar.start();
}
config_statusBarComponent在frameworks\base\packages\SystemUI\res\values\config.xml中定义:
<!-- Component to be used as the status bar service. Must implement the IStatusBar
interface. This name is in the ComponentName flattened format (package/class) -->
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
由此可见,SystemBars里面启动的就是PhoneStatusBar了,PhoneStatusBar继承BaseStatusBar。由Java多态性,mStatusBar.start()实际上就是PhoneStatusBar.start()。下面看一下PhoneStatusBar.start()这个函数的函数体:
@Override
public void start() {
……
super.start(); // calls createAndAddWindows()
// 添加导航栏
addNavigationBar();
}
super.start()也就是BaseStatusBar.start(),里面调用了createAndAddWindows(),但这是一个抽象函数,因此会回调至子类PhoneStatusBar的createAndAddWindows(),下面看一下PhoneStatusBar的createAndAddWindows()函数:
@Override
public void createAndAddWindows() {
……
addStatusBarWindow();
……
}
private void addStatusBarWindow() {
makeStatusBarView();
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}