赞
踩
Android中的Service分前台服务和后台服务两类:
前台服务会在通知栏有一条不能被手动清除的Notification,当此前台服务由于内存不足而被系统kill掉的时候,此Notification也会同时消失,用户由此得知此服务已经停止了,起到一个通知用户服务是否还在工作;
后台服务则没有类似的Notification,即使被系统kill掉,用户也不会得到什么通知。
Service通过调用方法 startForeground (int id, Notification notification)方法设置是否为前台任务,如:
- Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
- System.currentTimeMillis());
- Intent notificationIntent = new Intent(this, ViewServerActivity.class);
- PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
- notification.setLatestEventInfo(this, getText(R.string.notification_title,
- getText(R.string.notification_message), pendingIntent);
- startForeground(ONGOING_NOTIFICATION, notification);
由此代码引发了一个需要特别注意的事情,代码片段中的NOGOING_NOTIFICATION的值,不能是0,否则就不会显示出Notification,究其原因只能看源码了:
service startForeground()和stopForeground()源码:
- public final void startForeground(int id, Notification notification) {
- try {
- mActivityManager.setServiceForeground(
- new ComponentName(this, mClassName), mToken, id,
- notification, true);
- } catch (RemoteException ex) {
- }
- }
- public final void stopForeground(boolean removeNotification) {
- try {
- mActivityManager.setServiceForeground(
- new ComponentName(this, mClassName), mToken, 0, null,
- removeNotification);
- } catch (RemoteException ex) {
- }
- }
http://blog.csdn.net/stonecao/article/details/6579710
其实最终运行到的是ActiveServices类中的setServiceForegroundLocked方法:
- public void setServiceForegroundLocked(ComponentName className, IBinder token,
- int id, Notification notification, boolean removeNotification) {
- final int userId = UserHandle.getCallingUserId();
- final long origId = Binder.clearCallingIdentity();
- try {
- ServiceRecord r = findServiceLocked(className, token, userId);
- if (r != null) {
- if (id != 0) {
- if (notification == null) {
- throw new IllegalArgumentException("null notification");
- }
- if (r.foregroundId != id) {
- r.cancelNotification();
- r.foregroundId = id;
- }
- notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
- r.foregroundNoti = notification;
- r.isForeground = true;
- r.postNotification();
- if (r.app != null) {
- updateServiceForegroundLocked(r.app, true);
- }
- getServiceMap(r.userId).ensureNotStartingBackground(r);
- } else {
- if (r.isForeground) {
- r.isForeground = false;
- if (r.app != null) {
- mAm.updateLruProcessLocked(r.app, false, false);
- updateServiceForegroundLocked(r.app, true);
- }
- }
- if (removeNotification) {
- r.cancelNotification();
- r.foregroundId = 0;
- r.foregroundNoti = null;
- }
- }
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }

至此,我们应该很清楚了,如果传进来的id=0,则直接执行以下代码了:
- if (removeNotification) {
- r.cancelNotification();
- r.foregroundId = 0;
- r.foregroundNoti = null;
- }
最后直接cancleNotification(),所以传id=0,就相当于取消notification显示!
从google上的文档看到以下参数说明:
id | The identifier for this notification as per NotificationManager.notify(int, Notification) ; must not be 0. |
---|---|
notification | The Notification to be displayed. |
但是在我的eclipse中的javadoc却是看不到“must not be 0”的说明的!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。