Android 源码 屏蔽具体Notification策略

一、Notification源码浅析:

Notification是系统的通知类,所有的系统通知以及应用通知都会调用该API来进行内容的填充,完成具体的通知编辑,并通过NotificationManager的notify方法来发送出来。

1.Notification.java中执行内容填充的方法:

Notification.java路径一般如下:frameworks/base/core/java/android/app/Notification.java

Notification在6.0的源码中是如此实现的:

Notification.java有一个public的内部类,叫Builder;这个类会有我们常用的各个属性的set方法,如下图:

Android 源码 屏蔽具体Notification策略_第1张图片

Android 源码 屏蔽具体Notification策略_第2张图片

我们在使用Notification对象的时候,要求new一个Notification.Builder就是因为如此。Notification本身并不会有set和get方法来处理,而交给Builder来处理,这样可以保证内容的匿名性,防止被外部的类截获内容,一种安全的考虑吧。

而这些参数,比如ContentText、ContentTitle等,他的类型都是private

Android 源码 屏蔽具体Notification策略_第3张图片

这样就外部根本无法访问,所以真的太安全了,以至于我想get都没法get。

而在Notification new的时候呢,Builder就已经完成了他的工作,如图是Notification的构造函数:

Android 源码 屏蔽具体Notification策略_第4张图片

这是一个hide的方法,但是系统级的应用可以调用。

我们用的是另一个:

Android 源码 屏蔽具体Notification策略_第5张图片

做完这一切,我们会调用一个build()方法来完成,如图:

Android 源码 屏蔽具体Notification策略_第6张图片

这里是Builder的build()方法,我们发现它最后return了一个UnreadConversation对象(之后的不讨论了,主要是检测和执行序列化的作用)

Android 源码 屏蔽具体Notification策略_第7张图片

2.NotificationManager来显示Notification:

NotificationManager.java的路径:frameworks/base/core/java/android/app/NotificationManager.java

NotificationManager是Notification的一个管理类,他的启动是通过binder机制,获得一个Notification的binder来启动对应的系统服务,如图:

Android 源码 屏蔽具体Notification策略_第8张图片

启动了NotificationManager之后,调用notify方法就显示出来了,如图:

Android 源码 屏蔽具体Notification策略_第9张图片

下面的notify方法是最后调用的。(全过程)

二、Notification的屏蔽策略:

我们的目的是根据特性的contentText来屏蔽特定的notification;屏蔽的方式就是当判断他现实的是我们要屏蔽的notification的时候,我们不让他执行notify方法。所以,关键点就是在执行notify方法之前来确认我们的notification是特定的。

之前尝试了很多方法都不行,最后考虑了一下static的特性,如此才好。

static在java的内存中会分配一块区域,用来存放所有的全局类的变量;又因为notification本身设计的问题,无法通过get的方法拿到特性的contentText字段,notification解析也无法获得,因为他是内部类Builder来实现的,而Builder本身并不支持get操作。

所以,我们通过控制一个static标志位的方法来确定是否屏蔽当前notification;而标志位的判断在Builder内部完成,如此解决了问题。

对策如下:

Android 源码 屏蔽具体Notification策略_第10张图片

Android 源码 屏蔽具体Notification策略_第11张图片

你可能感兴趣的:(android知识类)