`
daibalusu
  • 浏览: 343720 次
文章分类
社区版块
存档分类
最新评论

SystemUI之:Notification前世今生

 
阅读更多

好久没写东西,我得承认,是自己懒了。

解过几个statusbarbug,觉得notification还是挺有意思的,分析一下流程,以作备忘吧。

  • 通知的接收

1.notification由系统或第三方应用封装发出notificationManager.notify()

2.通知进入一个队列NotificationManagerService.enqueueNotificationInternal()

3.在上面方法里面会发现一个熟悉的身影,就是mStatusBar,它是StatusBarManagerService的化身。调用mBar.addNotification(key,notification);

4.通过linux查找命令先定位IStatusBar.aidl的位置,然后在该最外路径下搜索IStatusBar.Stub可以找到具体实现它的java文件,这里我们找到了CommandQueue,java。然后调用CommandQueue. addNotification(),该方法利用handle发出一个消息:MSG_ADD_NOTIFICATION,跳转到回调函数addNotification(ne.key,ne.notification); PhoneStatusBar实现了这个回调方法。

5.以上一个通知算是被系统statusBar所接收到。

  • 通知的statusbar显示

public void addNotification(IBinder key, StatusBarNotification notification) {
    	// 1.初始化一个状态栏图标来体现该notification
        StatusBarIconView iconView = addNotificationViews(key, notification);
        if (iconView == null) return;
        }
        if (immersive) {
            //无实际作用,4.1会被注释
        } else if (notification.notification.fullScreenIntent != null) {
            // 2.not immersive & a full-screen alert should be shown,比如电话和闹钟的通知灰常nb
            Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
            try {
                notification.notification.fullScreenIntent.send();
            } catch (PendingIntent.CanceledException e) {
            }
        } else {
            // 3.usual case: status bar visible & not immersive。普通notification都走这道,用一个动画的形式显示该通知的文字信息。
            tick(notification);
        }

        // 4.Recalculate the position of the sliding windows and the titles.
        setAreThereNotifications();
        // 5.刷新一下ExpandedView的位置,
        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
    }

  • 通知的expendView显示

代码都在上一步走完了。

条目的添加是addNotificationViews()

// 1.Construct the expanded view.
   NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);

view的刷新是addNotification():

// 5.刷新一下ExpandedView的位置,
   updateExpandedViewPos(EXPANDED_LEAVE_ALONE);

  • 通知的更新

同样是从CommandQueue. updateNotification()开始走,然后到PhoneStatusBar. updateNotification()。代码流程和通知的添加几乎一致,只是没有add view这一步

  • 通知的发送

protected void sendNotification() {
		// TODO Auto-generated method stub
		Log.e(TAG, "-----sendNotifications----");
//		1.实例化intent和获取通知的服务。
		Intent mIntent = new Intent();
		 NotificationManager notificationManager = (NotificationManager) mContext
         .getSystemService(Context.NOTIFICATION_SERVICE);
		mIntent.setClass(mContext, ShowHello.class);
		PendingIntent mPendingIntent = PendingIntent.getActivity(mContext, 0, mIntent, 0);
//		2.设置通知的相应属性
//		mNotification.fullScreenIntent = mPendingIntent;//这句话的作用是决定通知是否自动弹出那个可跳转的activity。
		mNotification.defaults |= Notification.DEFAULT_SOUND;//设置通知是否播放声音。
		mNotification.flags = Notification.FLAG_ONGOING_EVENT;
//		在4.0的expendview里多显示一张图片,2.3系统会报错
		mNotification.largeIcon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_search);
//		显示通知调用下面的方法是必须的,但在api11会被deprecated,使用Notification.Builder代替。
		mNotification.setLatestEventInfo(mContext, tick, TAG, mPendingIntent);
//		3.唤醒通知
		notificationManager.notify(R.drawable.ic_launcher, mNotification);
	}

  • 各个主要版本的变化

分析时是以4.0为准,为了兼顾其他也顺便看了一遍2.3,4.1的流程,notification总的来说没有大的变化,API升级后有些方法被弃用有了新的实现,与之相关的就是状态栏为了适配pad和更高分辨率机型进行了一些重构,体现在我们这里就是2.3的statusBarService在4.0后改名为phoneStatueBar。4.0加入的immersive模式在4.1被彻底废除。

  • 三言两语

Notification的前世来生也就这样,生平中有过纠结的是NotificationManager,NotificationManagerService,StatusBarManagerService,phoneStatueBar,CommandQueue。

  • 资源下载

notification小DEMO,请CLICK ME
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics