AndroidNotification从notify到添加view的处理流程
Android版本:8.1
创建Notification是很容易的,android8.0以后开始加⼊通知渠道NotificationChannel,然后在构造NotificationCompat.Builder的时候,指定要发送的渠道,最后调⽤ify(id,notification)发送通知。
public void notify(int id, Notification notification)
{
notify(null, id, notification);
}
---------------
public void notify(String tag,int id, Notification notification)
{
notifyAsUr(tag, id, notification,new UrId()));
}
---------------
public void notifyAsUr(String tag,int id, Notification notification, UrHandle ur)
{
INotificationManager rvice =getService();
小学语文教研工作计划final Notification copy = Builder.maybeCloneStrippedForDelivery(notification, isLowRam);
...
try{
copy, ur.getIdentifier());
}catch(RemoteException e){
hrowFromSystemServer();
}
}
-------------------
static public INotificationManager getService()
{
if(sService != null){
火星人俱乐部return sService;
}
IBinder b = Service("notification");
sService = INotificationManager.Stub.asInterface(b);
return sService;
}
获取了INotificationManager 远程接⼝对象,把Notification 给加⼊到队列中,
INotificationManager的远程对象是NotificationManagerService⾥的mrvice,NotificationManagerService是系统服务。在开机启动的时候,Systemrver⾥和其他系统服务⼀起启动,最后注册到ServiceManager⾥。
publishBinderService(Context.NOTIFICATION_SERVICE, mService);//把rvice注册到Servicemanager⾥
----
private final IBinder mService =new INotificationManager.Stub(){
...
}
接着前⾯的,找到了enqueueNotificationWithTag
@Override
public void enqueueNotificationWithTag(String pkg, String opPkg, String tag,int id,
Notification notification,int urId)throws RemoteException {
enqueueNotificationInternal(pkg, opPkg, CallingUid(),
history是什么意思CallingPid(), tag, id, notification, urId);
}
------------
南洋理工大学void enqueueNotificationInternal(final String pkg,final String opPkg,final int callingUid, final int callingPid,final String tag,final int id,final Notification notification,
int incomingUrId){
....处理notification包含的信息,通知渠道,优先级。。
mHandler.post(new EnqueueNotificationRunnable(urId, r));
}
把notification转换为NotificationRecord,并post给EnqueueNotificationRunnable,
EnqueueNotificationRunnable的run⽅法⾥。
@Override
public void run(){
synchronized(mNotificationLock){
mEnqueuedNotifications.add(r);
scheduleTimeoutLocked(r);
...
mHandler.post(new Key()));
}
------------
@Override
public void run(){
synchronized(mNotificationLock){
try{
NotificationRecord r = null;
int N = mEnqueuedNotifications.size();
NotificationRecord old = (key);
final StatusBarNotification n = r.sbn;
final Notification notification = n.getNotification();
...
SmallIcon()!= null){
StatusBarNotification oldSbn =(old != null)? old.sbn : null;
if(oldSbn == null ||!Objects.Group(), n.getGroup())){
mHandler.post(new Runnable(){
@Override
public void run(){
n,hasAutoGroupSummaryLocked(n));
}
});
}
}
...
buzzBeepBlinkLocked(r);
}
------------
void buzzBeepBlinkLocked(NotificationRecord record){
处理notification的声⾳震动和灯光闪烁
}
-
-----------
public void notifyPostedLocked(StatusBarNotification sbn, StatusBarNotification oldSbn){发送给状态栏
mHandler.post(new Runnable(){
@Override
public void run(){
notifyPosted(info, sbnToPost, update);
}
});
}
↓
roi是什么意思private void notifyPosted(final ManagedServiceInfo info,
final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate){
三年级上册英语第一课
final INotificationListener listener =(INotificationListener) info.rvice;
StatusBarNotificationHolder sbnHolder =new StatusBarNotificationHolder(sbn);
try{
}catch(RemoteException ex){
Log.e(TAG,"unable to notify listener (posted): "+ listener, ex);
}
}
INotificationListener是另⼀个远程接⼝对象
protected class NotificationListenerWrapper extends INotificationListener.Stub
-
nubar-----------
@Override
public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
NotificationRankingUpdate update){
SomeArgs args = SomeArgs.obtain();includefile
args.arg1 = sbn;
args.arg2 = mRankingMap;
mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_POSTED,
args).ndToTarget();
}
ca MSG_ON_NOTIFICATION_POSTED:{
SomeArgs args =(SomeArgs) msg.obj;
StatusBarNotification sbn =(StatusBarNotification) args.arg1;
RankingMap rankingMap =(RankingMap) args.arg2;
onNotificationPosted(sbn, rankingMap);
------------
public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap){
onNotificationPosted(sbn);
}
public void onNotificationPosted(StatusBarNotification sbn){
// optional
}
很意外,发现⽅法是空的,那调这么多有什么⽤? 研究了⼀下发现,onNotificationPosted的这个⽅法属于的是public abstract class NotificationListenerService extends Service {
NotificationListenerService 是个抽象⽅法,那很⾃然调⽤的时候会调⽤它的⼦类,
然后
public class NotificationListenerWithPlugins extends NotificationListenerService
但是找了⼀圈NotificationListenerWithPlugins ,没有onNotificationPosted,那只有继续找它的⼦类了,
后来发现,在Statusbar⾥有个匿名内部类实现了NotificationListenerService 的⽅法。
private final NotificationListenerWithPlugins mNotificationListener =
new NotificationListenerWithPlugins(){
...
@Override
public void onNotificationPosted(final StatusBarNotification sbn,
final RankingMap rankingMap){
mHandler.post(new Runnable(){
@Override
public void run(){finisher
...
if(isUpdate){
updateNotification(sbn, rankingMap);
}el{
addNotification(sbn, rankingMap);
}
...
}
}
...
metaanalysis}
------------
public void addNotification(StatusBarNotification notification, RankingMap ranking)
throws InflationException {
Entry shadeEntry =createNotificationViews(notification);
boolean isHeadsUped =shouldPeek(shadeEntry);.
.
..
}
------------
protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn)
throws InflationException {
NotificationData.Entry entry =new NotificationData.Entry(sbn);
<(LeakDetector.class).trackInstance(entry);
// Construct the expanded view.
inflateViews(entry, mStackScroller);
}
-
-----------
protected void inflateViews(Entry entry, ViewGroup parent){
new RowInflaterTask().inflate(mContext, parent, entry,
row ->{
bindRow(entry, pmUr, sbn, row);
updateNotification(entry, pmUr, sbn, row);
});
}
最后bindRow就是去构造通知栏的通知View,然后updateNotification就是去显⽰到状态栏。