二、PhoneStatusBar.java
public class PhoneStatusBar extends StatusBar {
}
PhoneStatusBar 是StatusBar(extends SystemUI)的子类,真正和StatusBarManagerService交互的实际上就是它。
对于SystemUI,首先启动的是Start();
public void start() {
……
//调用StatusBar 的start方法,建立和StatusbarManagerService之间的联系
super.start();//在StatusBar的start中实现makeStatusBarView然后初始化statusbar icon状态
//启动更新Icon的方法
mIconPolicy = new PhoneStatusBarPolicy(mContext);
}
super.start()中我们看到,StatusBar是一个abstract类,真正要建立View是不能够的,必须在子类中创建。
实际上,StatusBar中也这样定义protected abstract View makeStatusBarView()
PhoneStatusBar 中:
protected View makeStatusBarView() {
final Context context = mContext;
Resources res = context.getResources();
//定义Icon的大小,缩放率和彼此间距
loadDimens();
mIconSize =
res.getDimensionPixelSize(com.Android.internal.R.dimen.status_bar_icon_size);
//状态栏下拉时的view
ExpandedView expanded = (ExpandedView)View.inflate(context,
R.layout.status_bar_expanded, null);
//真正显示的statusbar是根据是否是双卡来选择xml文件
PhoneStatusBarView sb;
if (TelephonyManager.getDefault().isMultiSimEnabled()) {
sb = (PhoneStatusBarView)View.inflate(context,
R.layout.msim_status_bar, null);
} else {
sb = (PhoneStatusBarView)View.inflate(context,
R.layout.status_bar, null);
}
//获取statusbar的实例
sb.mService = this;
mStatusBarView = sb;
//显示statusbar icon的view
mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);
//显示notification的view
mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);
mMoreIcon = sb.findViewById(R.id.moreIcon);
//定义下拉状态栏,显示Notifications
mExpandedDialog = new ExpandedDialog(context);
/*这个expanded就是指layout下的status_bar_expanded.xml解析所得下拉状态栏*/
mExpandedView = expanded;
//显示Notification的控件,NotificationRowLayout是处理函数,
mPile = (NotificationRowLayout)expanded.findViewById(R.id.latestItems);
mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
//android2.3中显示onGoing等信息的textview,android4.0已经不用了
mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);
mNoNotificationsTitle.setVisibility(View.GONE);
……
}
在步骤一的函数start()中的标识①处调用的是PhoneStatusBar的函数,在那里初始化status bar icon,
前面说了,在registerStatusBar时获得的iconList是没有icon的
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
//依据config.xml中的config_statusBarIcons定义的字符串创建StatusBarIconView,注意
//mContext是PhoneStatusBar的mContext
StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
//设置显示的icon
view.set(icon);
//添加到msim_status_bar.xml的保存icon的view中去
if (FeatureQuery.FEATURE_ANNUCIATOR_NEW_STATUSBAR_STYLE) {
mStatusIcons.addView(view, viewIndex,
new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, mIconSize));
} else {
mStatusIcons.addView(view, viewIndex,
new LinearLayout.LayoutParams(mIconSize, mIconSize));
}
}
在PhoneStatusBar.java中用到下面这两个类
StatusBarIconsView.java
public class StatusBarIconView extends AnimatedImageView
public StatusBarIconView(Context context, String slot, Notification notification) {
final Resources res = context.getResources();
mSlot = slot;
mNumberPain = new Paint();
mNumberPain.setTextAlign(Paint.Align.CENTER);
mNumberPain.setColor(res.getColor(R.drawable.notification_number_text_color));
mNumberPain.setAntiAlias(true);
mNotification = notification;
……
setScaleType(ImageView.ScaleType.CENTER);
}
}
由class的声明可以看出,StatusBarIconView 是一个AnimatedImageView,因此,可以显示icon
public boolean set(StatusBarIcon icon) {
final boolean iconEquals = mIcon != null
&& streq(mIcon.iconPackage, icon.iconPackage)
&& mIcon.iconId == icon.iconId;
final boolean levelEquals = iconEquals
&& mIcon.iconLevel == icon.iconLevel;
final boolean visibilityEquals = mIcon != null
&& mIcon.visible == icon.visible;
final boolean numberEquals = mIcon != null
&& mIcon.number == icon.number;
//将icon信息拷贝给mIcon
mIcon = icon.clone();
if (!iconEquals) {
Drawable drawable = getIcon(icon);
if (drawable == null) {
return false;
}
//下面两步就是获取drawable,然后设置到view中去
setImageDrawable(drawable);
}
}
private Drawable getIcon(StatusBarIcon icon) {
//我们在PhoneStatusBar中创建StatusBarIconView时传了mContext,因此这里getContext()
//也是PhoneStatusBar的
return getIcon(getContext(), icon);
}
public static Drawable getIcon(Context context, StatusBarIcon icon) {
……
try {
//获取icon
return r.getDrawable(icon.iconId);
} catch (RuntimeException e) {
}
return null;
}
只有在下面这个类中才正式显示icon在statusbar上
PhoneStatusBarPolicy.java
Context是PhoneStatusBar的mContext
public PhoneStatusBarPolicy(Context context) {
//StatusBarManagerService
mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
mStorageManager.registerListener(
new com.android.systemui.usb.StorageNotification(context));
// TTY status
mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0, null);
// Alarm clock
mService.setIcon("alarm_clock", R.drawable.stat_sys_alarm, 0, null);
mService.setIconVisibility("alarm_clock", false);
// volume
mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0, null);
mService.setIconVisibility("volume", false);
updateVolume();
//headset
mService.setIcon("headset", com.android.internal.R.drawable.stat_sys_headset, 0, null);
mService.setIconVisibility("headset", false);
}
上面的mService是StatusBarManager,那么setIcon是操作如下:
StatusBarManager.java
public void setIcon(String slot, int iconId, int iconLevel, String contentDescription) {
try {
//StatusBarManagerService的本地代理service
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);
}
}