前面三篇文章《Android 4.0 ICS SystemUI浅析——SystemUI启动流程》、《Android 4.0 ICS SystemUI浅析——StatusBar结构分析》、《Android 4.0 ICS SystemUI浅析——StatusBar加载流程分析》逐步分析了SystemUI中StatusBar的启动以及加载流程,本文主要分析StatusBar上的Notification的加载,如有不正之处还恳请各位帮忙指正。
本文来自:http://blog.csdn.net/yihongyuelan 欢迎转载 请务必注明出处!
在上一篇文章《Android 4.0 ICS SystemUI浅析——StatusBar加载流程分析》中,我们主要分析了StatusBar上的系统Icons加载的过程,包括了耳机图标、蓝牙图标、禁音图标等等,此文是紧接着上文分析的,因此我们首先看到/SourceCode/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java的start():
public void start() {
// First set up our views and stuff.首先准备我们需要显示的view以及原材料
//我们先跟踪这里的makeStatusBarView
View sb = makeStatusBarView();
// Connect in to the status bar manager service
//初始化各个存储器,用于存储各类信息,这些信息通过StatusBarManagerService获取
//iconsList用于存放icons
StatusBarIconList iconList = new StatusBarIconList();
//nodificationKeys保存以Binder为Key的notification
ArrayList<IBinder> notificationKeys = new ArrayList<IBinder>();
//保存StatusBarNotification类型的notifications
ArrayList<StatusBarNotification> notifications = new ArrayList<StatusBarNotification>();
//mCommandQueue是和IStatusBarService进行交互的IBinder
mCommandQueue = new CommandQueue(this, iconList);
//这里实际上获取的是StatusBarManagerService
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
int[] switches = new int[7];
ArrayList<IBinder> binders = new ArrayList<IBinder>();
try {
//通过StatusBarManagerService中的registerStatusBar来获取初始设置
mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications,
switches, binders);
} catch (RemoteException ex) {
// If the system process isn't there we're doomed anyway.
}
... ...
// Set up the initial notification state
//加载notifications,本文的分析主要从这里开始!
N = notificationKeys.size();
if (N == notifications.size()) {
for (int i=0; i<N; i++) {
addNotification(notificationKeys.get(i), notifications.get(i));
}
} else {
Log.wtf(TAG, "Notification list length mismatch: keys=" + N
+ " notifications=" + notifications.size());
}
... ...
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
lp.packageName = mContext.getPackageName();
lp.windowAnimations = R.style.Animation_StatusBar;
//在Window上显示StatusBar界面
WindowManagerImpl.getDefault().addView(sb, lp);
mDoNotDisturb = new DoNotDisturb(mContext);
}
我们可以看到addNotification()方法主要完成Notification图标的加载。跟进去看看(因为我们分析的是Phone因此选择PhoneStatusBar),代码如下:
public void addNotification(IBinder key, StatusBarNotification notification) {
//该方法主要构造Notification Icons以及Expaned View
StatusBarIconView iconView = addNotificationViews(key, notification);
if (iconView == null) return;
boolean immersive = false;
try {
//判断当前栈顶Activity是否具有android:immersive属性。该属性在Android 4.0中新加入的属性,如果该属性为true则该Activity不能被其他Activity或者Notification所打断。
immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
if (DEBUG) {
Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
}
} catch (RemoteException ex) {
}
//因为这里我们返回的是false,所以不会执行
if (immersive) {
if ((notification.notification.flags & Notification.FLAG_HIGH_PRIORITY) != 0) {
Slog.d(TAG, "Presenting high-priority notification in immersive activity");
// special new transient ticker mode
// 1. Populate mIntruderAlertView
ImageView alertIcon = (ImageView) mIntruderAlertView.findViewById(R.id.alertIcon);
TextView alertText = (TextView) mIntruderAlertView.findViewById(R.id.alertText);
alertIcon.setImageDrawable(StatusBarIconView.getIcon(
alertIcon.getContext(),
iconView.getStatusBarIcon()));
alertText.setText(notification.notification.tickerText);
View button = mIntruderAlertView.findViewById(R.id.intruder_alert_content);
button.setOnClickListener(
new NotificationClicker(notification.notification.contentIntent,
notification.pkg, notification.tag, notification.id));
// 2. Animate mIntruderAlertView in
mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
// 3. Set alarm to age the notification off (TODO