概述
1、概要
对于Phone来说SystemUI指的是:StatusBar(状态栏)、NavigationBar(导航栏)、Keyguard(锁屏)等等。
启动后Phone界面上的信号,蓝牙标志,Wifi标志等等这些状态显示标志都会在StatusBar上显示。当我们的设备开机后,首先需要给用户呈现的就是各种界面同时也包括了我们的SystemUI,因此对于整个Android系统来说,SystemUI都有举足轻重的作用。
本篇主要解析SystemUI中StatusBar的代码流程。
2、SystemUI截图
贴几张垃圾图,供新人更好的了解SystemUI
3、SystemUI的大致启动流程图(网上找的,与最新的处理流程并没有太大出入)
4、SystemUI启动流程代码解析
4.1、启动SystemUIService
SystemServer.java
从AndroidManifest.xml中可以看到SystemUIService,
<service android:name="SystemUIService"
android:exported="true"
/>
上面的SystemUIService是在SystemServer中启动的
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);
}
4.2、启动相应的服务
SystemUIService.java
在SystemUIService中的onCreate()方法中调用了SystemUIApplication的startServicesIfNeeded()方法.
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
而在SystemUIApplication中,首先把需要启动的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() {
.....
Log.v(TAG, "Starting SystemUI services.");
final int N = SERVICES.length;
for (int i=0; i<N; i++) {
Class<?> cl = SERVICES[i];
if (DEBUG) Log.d(TAG, "loading: " + cl);
try {
mServices[i] = (SystemUI)cl.newInstance();
}
........
mServices[i].mContext = this;
mServices[i].mComponents = mComponents;
if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
mServices[i].start();
......
}
4.3、启动SystemBar
SystemBars.java
已com.android.systemui.statusbar.SystemBars.class为例:
public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks {
@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
}
ServiceMonitor.java
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);
}
主线程接受消息后调用startService启动服务.
private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch(msg.what) {
case MSG_START_SERVICE:
startService();
break;
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);
}
}
private ComponentName getComponentNameFromSetting() {
String cn = Settings.Secure.getStringForUser(mContext.getContentResolver(),
mSettingKey, UserHandle.USER_CURRENT);
return cn == null ? null : ComponentName.unflattenFromString(cn);
}
SystemBars.java
@Override
public void onNoService() {
if (DEBUG) Log.d(TAG, "onNoService");
createStatusBarFromConfig(); // fallback to using an in-process implementation
}
private void 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);
} .....
try {
mStatusBar = (BaseStatusBar) cls.newInstance();
} ....
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
//这里是调用的BaseStatusBar的start()方法,当有子类继承时,直接调用.
mStatusBar.start();
}
PhoneBar.java
@Override
public void start() {
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
updateDisplaySize();
mScrimSrcModeEnabled = mContext.getResources().getBoolean(
R.bool.config_status_bar_scrim_behind_use_src);
//PhoneBar继承了BaseStatusBar,所以也需要重写基类的方法,同时调用基类的start().
super.start(); // calls createAndAddWindows()
mMediaSessionManager= (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
// TODO: use MediaSessionManager.SessionListener to hook us up to future updates
// in session state
addNavigationBar();
// Lastly, call to the icon policy to install/update all the icons.
mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController);
mSettingsObserver.onChange(false); // set up
mHeadsUpObserver.onChange(true); // set up
}
BaseStatusBar.java
public void start() {
........
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
.......
// Connect in to the status bar manager service
StatusBarIconList iconList = new StatusBarIconList();
mCommandQueue = new CommandQueue(this, iconList);
int[] switches = new int[8];
ArrayList<IBinder> binders = new ArrayList<IBinder>();
try {
mBarService.registerStatusBar(mCommandQueue, iconList, switches, binders);
}
createAndAddWindows();
......
// Set up the initial icon state
int N = iconList.size();
int viewIndex = 0;
for (int i=0; i<N; i++) {
StatusBarIcon icon = iconList.getIcon(i);
if (icon != null) {
addIcon(iconList.getSlot(i), i, viewIndex, icon);
viewIndex++;
}
}
.........
}
BaseStatusBar.java这里的createAndAddWindows和addIcon等的实现是在BaseStatusBar的子类中,以PhoneStatusBar.java为例:
public void createAndAddWindows() {
addStatusBarWindow();
}
private void addStatusBarWindow() {
makeStatusBarView();
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}
protected PhoneStatusBarView makeStatusBarView() {
.......
//定义StatusBarWindow
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
mStatusBarWindow.mService = this;
mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
checkUserAutohide(v, event);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mExpandedVisible) {
animateCollapsePanels();
}
}
return mStatusBarWindow.onTouchEvent(event);
}});
//定义StatusBarView
mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
mStatusBarView.setBar(this);
PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
mStatusBarView.setPanelHolder(holder);
mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
R.id.notification_panel);
mNotificationPanel.setStatusBar(this);
........
//定义expanded status bar
mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
mShowCarrierInPanel = (mCarrierLabel != null);
.........
return mStatusBarView;
}
前面提到,在BaseStatusBar.start()中调用addIcon去加载icon,其实现也在PhoneStatusBar.java中。
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
//初始化StatusBarIconView
StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
view.set(icon);//加载icon
//将设置好icon的StatusBarIconView加载到mStatusIcons布局中
mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, mIconSize));
view = new StatusBarIconView(mContext, slot, null);
view.set(icon);
mStatusIconsKeyguard.addView(view, viewIndex, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, mIconSize));
}
通过查看StatusBarIconView的继承关系我们可以发现public class StatusBarIconView extends AnimatedImageView ,继续跟踪可以看到public class AnimatedImageView extends ImageView,也就是说我们的StatusBarIconView其实就是一个封装过的ImageView,这样自然能够盛放我们的Icons了.
PhoneStatusBarPolicy.java
在前面的PhoneStatusBar.start()中, 开始icon加载:
// Lastly, call to the icon policy to install/update all the icons.
mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController);
从PhoneStatusBarPolicy的构造参数中,可以看到:
public PhoneStatusBarPolicy(Context context, CastController cast, HotspotController hotspot) {
mContext = context;
mCast = cast;
mHotspot = hotspot;
mService =(StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
// listen for broadcasts
IntentFilter filter = new IntentFilter();
filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
filter.addAction(Intent.ACTION_USER_SWITCHED);
// SPRD: fixbug421569 ADD headset icon in statusbar
filter.addAction(Intent.ACTION_HEADSET_PLUG);
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
// TTY status
mService.setIcon(SLOT_TTY, R.drawable.stat_sys_tty_mode, 0, null);
mService.setIconVisibility(SLOT_TTY, false);
.........
}
对象mService属于StatusBarManager的实例,所以会进入StatusBarManager类:
StatusBarManager.java
public void setIcon(String slot, int iconId, int iconLevel, String contentDescription) {
try {
final IStatusBarService svc = getService();
if (svc != null) {
svc.setIcon(slot, mContext.getPackageName(), iconId, iconLevel,
contentDescription);
}
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
}
}
StatusBarManagerService.java
public class StatusBarManagerService extends IStatusBarService.Stub {
private volatile IStatusBar mBar;
private StatusBarIconList mIcons = new StatusBarIconList();
public void setIcon(String slot, String iconPackage, int iconId, int iconLevel,
String contentDescription) {
enforceStatusBar();
synchronized (mIcons) {
int index = mIcons.getSlotIndex(slot);
StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId,
iconLevel, 0,contentDescription);
mIcons.setIcon(index, icon);
if (mBar != null) {
try {
mBar.setIcon(index, icon);
} catch (RemoteException ex) {
}
}
}
}
StatusBarIconList.java
public void setIcon(int index, StatusBarIcon icon) {
mIcons[index] = icon.clone();
}
CommandQueue.java
public class CommandQueue extends IStatusBar.Stub {
private StatusBarIconList mList;
private Callbacks mCallbacks;
private Handler mHandler = new H();
...
public void setIcon(int index, StatusBarIcon icon) {
synchronized (mList) {
int what = MSG_ICON | index;
mHandler.removeMessages(what);
mHandler.obtainMessage(what, OP_SET_ICON, 0, icon.clone()).sendToTarget();
}
}
}
private final class H extends Handler {
public void handleMessage(Message msg) {
final int what = msg.what & MSG_MASK;
switch (what) {
case MSG_ICON: {
final int index = msg.what & INDEX_MASK;
final int viewIndex = mList.getViewIndex(index);
switch (msg.arg1) {
case OP_SET_ICON: {
StatusBarIcon icon = (StatusBarIcon)msg.obj;
StatusBarIcon old = mList.getIcon(index);
if (old == null) {
mList.setIcon(index, icon);
mCallbacks.addIcon(mList.getSlot(index), index, viewIndex, icon);
} else {
List.setIcon(index, icon);
mCallbacks.updateIcon(mList.getSlot(index), index, viewIndex,old, icon);
}
break;
}
接下来又是回到BaseStatusBar.java中,接着回到PhoneStatusBar中执行addIcon():
public abstract class BaseStatusBar extends SystemUI implements CommandQueue{
public class PhoneStatusBar extends BaseStatusBar implements DemoMode{
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
view.set(icon);
mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, mIconSize));
view = new StatusBarIconView(mContext, slot, null);
view.set(icon);
mStatusIconsKeyguard.addView(view, viewIndex, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, mIconSize));
}
最后,将图标添加至状态栏上.
补充:
StatusBarManagerService.java
public StatusBarManagerService(Context context, WindowManagerService windowManager) {
mContext = context;
mWindowManager = windowManager;
//这里加载了系统预置的所有icon,路径在:./frameworks/base/core/res/res/values/config.xml
final Resources res = context.getResources(); mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));
LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
}
StatusBarManagerService是在SystemServer中启动的.
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);
}
}
以上是详细的对SystemUI 中的最重要的 StatusBar代码流程分析。
6、相关资源位置
代码位置:/frameworks/base/packages/SystemUI
初出江湖,希望各路大神&&前辈多多指点,晚辈拜谢~~~
最后
以上就是鲜艳大树为你收集整理的android5.1_SystemUI启动流程1、概要2、SystemUI截图 3、SystemUI的大致启动流程图(网上找的,与最新的处理流程并没有太大出入) 4、SystemUI启动流程代码解析4.1、启动SystemUIService6、相关资源位置的全部内容,希望文章能够帮你解决android5.1_SystemUI启动流程1、概要2、SystemUI截图 3、SystemUI的大致启动流程图(网上找的,与最新的处理流程并没有太大出入) 4、SystemUI启动流程代码解析4.1、启动SystemUIService6、相关资源位置所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复