com.android.systemui.SystemUIService.java
查看代码发现,启动机器,会去启动SystemUI的SystemUIService,而这个service的入口就是onCreate()方法。
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
com.android.systemui.SystemUIApplication.java
创建了一个集合,这个集合里面装的都是SystenUI的子类的全类名,但是有一个例外,”Divider.class”而没有写成”com.android.systemui.stackdivider.Divider.class” ?
private final SystemUI[] mServices = new SystemUI[SERVICES.length];
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,
Divider.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,
com.android.systemui.keyboard.KeyboardUI.class,
com.android.systemui.tv.pip.PipUI.class,
com.android.systemui.shortcut.ShortcutKeyDispatcher.class
};
public void startServicesIfNeeded() {
startServicesIfNeeded(SERVICES);
}
根据SERVICES这个集合提供的全类名,通过反射的方式来得到具体实例,然后再调用start()方法启动相应模块。其中onBootCompleted()这个方法只有recent、keyguard模块实现了。
private void startServicesIfNeeded(Class<?>[] services) {
if (mServicesStarted) {
return;
}
final int N = services.length;
for (int i=0; i<N; i++) {
Class<?> cl = services[i];
try {
Object newService = SystemUIFactory.getInstance().createInstance(cl);
mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
mServices[i].mComponents = mComponents;
mServices[i].start();
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
mServicesStarted = true;
}
com.android.systemui.statusbar.SystemBars
从SystemUI的流程分析中知道,在启动SystemUI的时候会指定启动SystemBars.class这个类的start()方法。
private ServiceMonitor mServiceMonitor;
public void start() {
mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
mServiceMonitor.start(); // will call onNoService if no remote service is found
}
com.android.systemui.statusbar.ServiceMonitor
这个类的start()方法,主要就是这三件事,监听文件、注册广播、启动服务(实际没有启动服务?)
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.addAction(Intent.ACTION_PACKAGE_REMOVED);//一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播)
filter.addDataScheme("package");
mContext.registerReceiver(mBroadcastReceiver, filter);
mHandler.sendEmptyMessage(MSG_START_SERVICE);//会调用startService()方法
}
在startService()方法先是试图获取服务的类名,但是通过重启机器的日志发现这个
mServiceName ==null,所以还是会回调到上一个类的onNoService()方法。
private void startService() {
mServiceName = getComponentNameFromSetting();
if (mDebug) Log.d(mTag, "startService mServiceName=" + mServiceName);
if (mServiceName == null) {
mBound = false;
mCallbacks.onNoService();
} else {
long delay = mCallbacks.onServiceStartAttempt();
mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay);
}
}
com.android.systemui.statusbar.SystemBars
因为SystemBars实现了上面的Callbacks接口,所以会调到这个方法。
@Override
public void onNoService() {
createStatusBarFromConfig(); // fallback to using an in-process implementation
}
通过查找发现config_statusBarComponent==com.android.systemui.statusbar.phone.PhoneStatusBar,所以下面的cls.newInstance()得到的实际上就是PhoneStatusBar的实例,然后调用其start()方法。之后就是进入PhoneStatusBar类了。
private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
final String clsName = mContext.getString(R.string.config_statusBarComponent);
if (clsName == null || clsName.length() == 0) {
throw andLog("No status bar component configured", null);
}
Class<?> cls = null;
try {
cls = mContext.getClassLoader().loadClass(clsName);
} catch (Throwable t) {
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
mStatusBar = (BaseStatusBar) cls.newInstance();
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}
com.android.systemui.statusbar.phone.PhoneStatusBar
PhoneStatusBar extends BaseStatusBar,而在BASEStatusBar的start()方法里面调用了createAndAddWindows(),并且由PhoneStatusBar 来实现该方法。
@Override
public void start() {
...
super.start(); // calls createAndAddWindows()
...
}
@Override
public void createAndAddWindows() {
addStatusBarWindow();
}
这个方法的主要作用,先是view的一些初始化操作,然后再将StatusBarWindowView添加到StatusBarWindowManager上。
private void addStatusBarWindow() {
makeStatusBarView();
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
mRemoteInputController = new RemoteInputController(mStatusBarWindowManager,
mHeadsUpManager);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}
这个方法的主要作用是对PhoneStatusBarView 的初始化,并返回这个对象,其中初始化的东西比较多,比如:通知栏、状态栏
protected PhoneStatusBarView makeStatusBarView() {
...
inflateStatusBarWindow(context);//加载布局mStatusBarWindow = R.layout.**super_status_bar
...
mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
R.id.notification_panel);//通知栏
//状态栏
mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
...
mBatteryController = createBatteryController();//电池状态监听广播(可以获取电池信息)
//网络监听
mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
mHotspotController = new HotspotControllerImpl(mContext);//热点控制器
mBluetoothController = new BluetoothControllerImpl(mContext, getLooper());//蓝牙控制器
mSecurityController = new SecurityControllerImpl(mContext);//安全控制器
......//各种状态栏图标的控制器
}