转载自:http://fortianwei.iteye.com/blog/1180020
相关文件:
framework/base/core/java/android/app/NotificationManager.java
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中:
- 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);
- }
-
注册状态栏管理和通知管理这两个服务。
2>.在StatusBarManagerService.java中,有addNotification,removeNotification,updateNotification等方法用于管理传递给他的通知对象。这个类是一些管理方法,实际执行相关动作的是在IStatusBar.java里面,这个是framework/base/core/java/com/android/internal/statusbar/IStatusBar.aidl自动生成的用于IPC的类。
拿addNotification方法示范:
- 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的实例
- volatile IStatusBar mBar;
为了防止NPE,每次使用mBar都先判断是否为null,mBar是在方法registerStatusBar中传递进来的。
- 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());
- }
- }
- }
framework/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java实现IStatusBar.java接口,
framework/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java提供IStatusBar相关服务。
CommandQueue.java中,IStatusBar.java里面对应的方法是用callback的形式调用的,callback的实现当然就在对应的服务提供类也就是StatusBarService.java中提供的啦。
CommandQueue.java中:
- 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();
-
-
-
-
- }
- }
在StatusBarService.java中:
- mCommandQueue = new CommandQueue(this, iconList);
- mBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.getService(Context.STATUS_BAR_SERVICE));
- try {
-
- mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications);
- } catch (RemoteException ex) {
-
- }
最终执行状态栏更新通知等事件都是在实现的CommandQueue.Callbacks里面执行。还是以addNotification为例:
- 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;
-
大致流程就是:调用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的具体处理方法。
摘取部分代码片段看看:
- 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了。
-
- static public INotificationManager getService()
- {
- if (sService != null) {
- return sService;
- }
- IBinder b = ServiceManager.getService("notification");
- sService = INotificationManager.Stub.asInterface(b);
- return sService;
- }
再看看更熟悉的notify方法,其实是执行:
- 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) {
- }
- }
service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut);也就是3中提到的那个对外公开的服务方法了,这样就进入了上面提到的处理流程了。
分析比较好的博客地址:http://blog.csdn.net/longwuxu/article/details/25542199