framework/base/services/java/com/android/server/NotificationManagerService.java{@hide} extends INotificationManager.Stub
framework/base/services/java/com/android/server/StatusBarManagerService.java extends IStatusBarService.Stub
framework/base/core/java/com/android/internal/statusbar/StatusBarNotification implements Parcelable
framework/base/core/java/com/android/internal/statusbar/IStatusBar.aidl
framework/base/core/java/com/android/internal/statusbar/IStatusBarService.aidl
framework/base/core/java/com/android/internal/statusbar/StatusBarNotification.aidl
framework/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java extends Service implements CommandQueue.Callbacks
framework/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java extends IStatusBar.Stub
1>.系统启动的时候:framework/base/services/java/com/android/server/SystemServer.java中:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
try
{
Slog.i(TAG,
"Status Bar"
);
statusBar =
new
StatusBarManagerService(context);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
}
catch
(Throwable e) {
Slog.e(TAG,
"Failure starting StatusBarManagerService"
, e);
}
try
{
Slog.i(TAG,
"Notification Manager"
);
notification =
new
NotificationManagerService(context, statusBar, lights);
ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
}
catch
(Throwable e) {
Slog.e(TAG,
"Failure starting Notification Manager"
, e);
}
|
这段代码是 注册状态栏管理和通知管理这两个服务。
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public
IBinder addNotification(StatusBarNotification notification) {
synchronized
(mNotifications) {
IBinder key =
new
Binder();
mNotifications.put(key, notification);
if
(mBar !=
null
) {
try
{
mBar.addNotification(key, notification);
}
catch
(RemoteException ex) {
}
}
return
key;
}
}
|
这里的mBar其实就是IStatusBar的实例
01
|
volatile
IStatusBar mBar;
|
为了防止NPE,每次使用mBar都先判断是否为null,mBar是在方法registerStatusBar中传递进来的。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
public
void
registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
List<IBinder> notificationKeys, List<StatusBarNotification> notifications) {
enforceStatusBarService();
Slog.i(TAG,
"registerStatusBar bar="
+ bar);
mBar = bar;
synchronized
(mIcons) {
iconList.copyFrom(mIcons);
}
synchronized
(mNotifications) {
for
(Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
notificationKeys.add(e.getKey());
notifications.add(e.getValue());
}
}
}
|
01
02
03
04
05
06
07
08
09
10
11
12
|
public
void
addNotification(IBinder key, StatusBarNotification notification) {
synchronized
(mList) {
NotificationQueueEntry ne =
new
NotificationQueueEntry();
ne.key = key;
ne.notification = notification;
mHandler.obtainMessage(MSG_ADD_NOTIFICATION,
0
,
0
, ne).sendToTarget();
//这句话对应的mHandler执行语句是:
// final NotificationQueueEntry ne = (NotificationQueueEntry)msg.obj;
// mCallbacks.addNotification(ne.key, ne.notification);
//也就是调用回调函数里面的addNotification。
}
}
|
在StatusBarService.java中:
01
02
03
04
05
06
07
08
09
|
mCommandQueue =
new
CommandQueue(
this
, iconList);
//StatusBarService实现了CommandQueue中的CommandQueue.Callbacks接口
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
try
{
//将IStatusBar实现类的对象传递到StatusBarManagerService.java中,这里的mCommandQueue就是上面对应的mBar啦。
mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications);
}
catch
(RemoteException ex) {
// If the system process isn't there we're doomed anyway.
}
|
最终执行状态栏更新通知等事件都是在实现的CommandQueue.Callbacks里面执行。还是以addNotification为例:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public
void
addNotification(IBinder key, StatusBarNotification notification) {
boolean
shouldTick =
true
;
if
(notification.notification.fullScreenIntent !=
null
) {
shouldTick =
false
;
Slog.d(TAG,
"Notification has fullScreenIntent; sending fullScreenIntent"
);
try
{
notification.notification.fullScreenIntent.send();
}
catch
(PendingIntent.CanceledException e) {
}
}
StatusBarIconView iconView = addNotificationViews(key, notification);
if
(iconView ==
null
)
return
;
//。。。以下省略N字。
|
大致流程就是:调用StatusBarManagerService.java中的addNotification方法->(mBar不为空的话)执行mBar.addNotification(key, notification);->对应的是CommandQueue中的addNotification(IBinder key, StatusBarNotification notification)->CommandQueue中的mCallbacks.addNotification(ne.key, ne.notification);->StatusBarService中的addNotification。
3>.上面是提供相关功能的一些类,具体的notification的管理类是framework/base/services/java/com/android/server/NotificationManagerService.java,从该类的定义public class NotificationManagerService extends INotificationManager.Stub可以知道
他是用来实现接口中INotificationManager中定义的相关方法并向外部提供服务的类。主要向外提供public void enqueueNotificationWithTag(String pkg, String tag, int id, Notification notification,int[] idOut)方法。该方法实际上是调用public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid,String tag, int id, Notification notification, int[] idOut),他里面提供了notification的具体处理方法。
摘取部分代码片段看看:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
if
(notification.icon !=
0
) {
StatusBarNotification n =
new
StatusBarNotification(pkg, id, tag,
r.uid, r.initialPid, notification);
if
(old !=
null
&& old.statusBarKey !=
null
) {
r.statusBarKey = old.statusBarKey;
long
identity = Binder.clearCallingIdentity();
try
{
mStatusBar.updateNotification(r.statusBarKey, n);
}
finally
{
Binder.restoreCallingIdentity(identity);
}
}
else
{
//省略。。。
|
当判断好需要更新通知的时候调用mStatusBar.updateNotification(r.statusBarKey, n);方法,这个就是StatusBarManagerService.java中的addNotification方法,这样就进入上面所说的处理流程了。
4>. 在3中的NotificationManagerService.java是管理notification的服务,服务嘛就是用来调用的,调用他的就是大家熟悉的NotificationManager了。
在NotificationManager.java中,有一个隐藏方法,用来得到INotificationManager接口对应的服务提供类,也就是NotificationManagerService了。
01
02
03
04
05
06
07
08
09
10
|
/** @hide */
static
public
INotificationManager getService()
{
if
(sService !=
null
) {
return
sService;
}
IBinder b = ServiceManager.getService(
"notification"
);
sService = INotificationManager.Stub.asInterface(b);
return
sService;
}
|
再看看更熟悉的notify方法,其实是执行:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public
void
notify(String tag,
int
id, Notification notification)
{
int
[] idOut =
new
int
[
1
];
INotificationManager service = getService();
String pkg = mContext.getPackageName();
if
(localLOGV) Log.v(TAG, pkg +
": notify("
+ id +
", "
+ notification +
")"
);
try
{
service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut);
if
(id != idOut[
0
]) {
Log.w(TAG,
"notify: id corrupted: sent "
+ id +
", got back "
+ idOut[
0
]);
}
}
catch
(RemoteException e) {
}
}
|
ervice.enqueueNotificationWithTag(pkg, tag, id, notification, idOut);也就是3中提到的那个对外公开的服务方法了,这样就进入了上面提到的处理流程了。