本篇介绍,NotificationListenerService和NotificationManagerService的相互跨进程通讯源码走向。
1. 了解NotificationListenerService:
NotificationListenerService是一个抽象类的Service。
public abstract class NotificationListenerService extends Service {
//......省略部分源码
@Override
public IBinder onBind(Intent intent) {
if (mWrapper == null) {
mWrapper = new NotificationListenerWrapper();
}
return mWrapper;
}
@Override
public void onDestroy() {
onListenerDisconnected();
super.onDestroy();
}
//......省略部分源码
}
重写了onBinde()
和onDestroy()
方法,给远程进程Binder通讯,和断开连接的通知。
2. NotificationManagerSevice如何通知NotificationListenerService
接下来,内部类NotificationListenerWrapper是 INotificationListener.Stub 的子类,用于远程NotificationManagerServer进程的通讯。
protected class NotificationListenerWrapper extends INotificationListener.Stub {
@Override
public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
NotificationRankingUpdate update) {
StatusBarNotification sbn;
try {
sbn = sbnHolder.get();
} catch (RemoteException e) {
Log.w(TAG, "onNotificationPosted: Error receiving StatusBarNotification", e);
return;
}
try {
// convert icon metadata to legacy format for older clients
createLegacyIconExtras(sbn.getNotification());
maybePopulateRemoteViews(sbn.getNotification());
} catch (IllegalArgumentException e) {
// warn and drop corrupt notification
Log.w(TAG, "onNotificationPosted: can't rebuild notification from " +
sbn.getPackageName());
sbn = null;
}
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
synchronized (mLock) {
applyUpdateLocked(update);
if (sbn != null) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = sbn;
args.arg2 = mRankingMap;
mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_POSTED,
args).sendToTarget();
} else {
// still pass along the ranking map, it may contain other information
mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_RANKING_UPDATE,
mRankingMap).sendToTarget();
}
}
}
//......省略部分源码
}
说简答点,在NotificationManagerServer系统服务,当Notification发生状态改变,就会远程调用NotificationListenerWrapper中方法,从而通知到NotificationListenerService监听。
查看下NotificationManagerServer中的源码:
private void notifyPosted(final ManagedServiceInfo info,
final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate) {
final INotificationListener listener = (INotificationListener)info.service;
StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
try {
listener.onNotificationPosted(sbnHolder, rankingUpdate);
} catch (RemoteException ex) {
Log.e(TAG, "unable to notify listener (posted): " + listener, ex);
}
}
NotificationManagerService会通过INotificationListener对象远程调用各种状态方法,从而通知到监听器。
接下来,回到NotificationListenerService类中,看到mHandler,将远程NotificationManagerService所在的进程发出的通知,发送到Handler中,从而交给NotificationListenerService所在的进程处理。
查看内部的Handler子类:
private final class MyHandler extends Handler {
public static final int MSG_ON_NOTIFICATION_POSTED = 1;
public static final int MSG_ON_NOTIFICATION_REMOVED = 2;
public static final int MSG_ON_LISTENER_CONNECTED = 3;
public static final int MSG_ON_NOTIFICATION_RANKING_UPDATE = 4;
public static final int MSG_ON_LISTENER_HINTS_CHANGED = 5;
public static final int MSG_ON_INTERRUPTION_FILTER_CHANGED = 6;
public MyHandler(Looper looper) {
super(looper, null, false);
}
@Override
public void handleMessage(Message msg) {
if (!isConnected) {
return;
}
switch (msg.what) {
case MSG_ON_NOTIFICATION_POSTED: {
SomeArgs args = (SomeArgs) msg.obj;
StatusBarNotification sbn = (StatusBarNotification) args.arg1;
RankingMap rankingMap = (RankingMap) args.arg2;
args.recycle();
onNotificationPosted(sbn, rankingMap);
} break;
case MSG_ON_NOTIFICATION_REMOVED: {
SomeArgs args = (SomeArgs) msg.obj;
StatusBarNotification sbn = (StatusBarNotification) args.arg1;
RankingMap rankingMap = (RankingMap) args.arg2;
args.recycle();
onNotificationRemoved(sbn, rankingMap);
} break;
case MSG_ON_LISTENER_CONNECTED: {
onListenerConnected();
} break;
case MSG_ON_NOTIFICATION_RANKING_UPDATE: {
RankingMap rankingMap = (RankingMap) msg.obj;
onNotificationRankingUpdate(rankingMap);
} break;
case MSG_ON_LISTENER_HINTS_CHANGED: {
final int hints = msg.arg1;
onListenerHintsChanged(hints);
} break;
case MSG_ON_INTERRUPTION_FILTER_CHANGED: {
final int interruptionFilter = msg.arg1;
onInterruptionFilterChanged(interruptionFilter);
} break;
}
}
}
Handler会根据远程进程发送过来的各种状态,处理,从而响应对应的方法。
3.注册到NotificationManagerService中:
再来看下NotificationListenerService的注册方法:
@SystemApi
public void registerAsSystemService(Context context, ComponentName componentName,
int currentUser) throws RemoteException {
if (mWrapper == null) {
mWrapper = new NotificationListenerWrapper();
}
mSystemContext = context;
INotificationManager noMan = getNotificationInterface();
mHandler = new MyHandler(context.getMainLooper());
mCurrentUser = currentUser;
noMan.registerListener(mWrapper, componentName, currentUser);
}
/** @hide */
protected final INotificationManager getNotificationInterface() {
if (mNoMan == null) {
mNoMan = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
}
return mNoMan;
}
该方法是将NotificationListenerWrapper对象传递到NotificationManagerService中,从而增加监听器。
再来到NotificationManagerService中:
private final IBinder mService = new INotificationManager.Stub() {
@Override
public void registerListener(final INotificationListener listener,
final ComponentName component, final int userid) {
enforceSystemOrSystemUI("INotificationManager.registerListener");
mListeners.registerService(listener, component, userid);
}
}
将每个NotificationListenerWrapper对象都收集起来,当Notification发生改变的时候,从而for循环,通知每个NotificationListenerWrapper,发送信息到Handler中,调用NotificationListenerService中对应方法。
总结一下:
- NotificationListenerService将 NotificationListenerWrapper对象,跨进程添加到NotificationManagerServce中,作为监听器。
- 当NotificationManagerService中察觉到Notification发生改变,从而for循环方式,跨进程通知每个NotificationListenerWrapper。
- NotificationListenerWrapper中的被通知的信息,发送到NotificationListenerService类中的Handler中处理,从而调用对应的方法。