Android 7.0 NotificationListenerService源码分析

本篇介绍,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中处理,从而调用对应的方法。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值