展会信息港展会大全

Notification framework层的处理流程分析
来源:互联网   发布日期:2015-10-02 21:52:46   浏览:1689次  

导读:google了一段时间发现没人写notification在framework中具体怎么实现的,感到很奇怪,是我搜索有问题?哎,不管了,反正工作需要,自己琢磨琢磨吧。相关文件...

google了一段时间发现没人写notification在framework中具体怎么实现的,感到很奇怪,是我搜索有问题?哎,不管了,反正工作需要,自己琢磨琢磨吧。

相关文件:

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.javaextends IStatusBarService.Stub

framework/base/core/java/com/android/internal/statusbar/StatusBarNotificationimplements 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中: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方法示范:

Java代码

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的实例

Java代码

volatile IStatusBar mBar;

为了防止NPE,每次使用mBar都先判断是否为null,mBar是在方法registerStatusBar中传递进来的。

Java代码

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中:

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();

//这句话对应的mHandler执行语句是:

//final NotificationQueueEntry ne = (NotificationQueueEntry)msg.obj;

// mCallbacks.addNotification(ne.key, ne.notification);

//也就是调用回调函数里面的addNotification。

}

}

在StatusBarService.java中:

Java代码

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为例:

Java代码

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的具体处理方法。

摘取部分代码片段看看:

Java代码

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了。

Java代码

/** @hide */

static public INotificationManager getService()

{

if (sService != null) {

return sService;

}

IBinder b = ServiceManager.getService("notification");

sService = INotificationManager.Stub.asInterface(b);

return sService;

}

再看看更熟悉的notify方法,其实是执行:

Java代码

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中提到的那个对外公开的服务方法了,这样就进入了上面提到的处理流程了。

作者“空之境界”

赞助本站

人工智能实验室

相关热词: android开发 教程

相关内容
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港