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) {        }    }

可见是有mActivityManager.setServiceForeground()里面做了封装,mActivityManager是一个IActivityManager接口的实现类,此接口实现类的关系具体参考此博文:

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上的文档看到以下参数说明:

Parameters
id The identifier for this notification as per NotificationManager.notify(int, Notification); must not be 0.
notification The Notification to be displayed.
See Also
  • stopForeground(boolean)

但是在我的eclipse中的javadoc却是看不到“must not be 0”的说明的!


更多相关文章

  1. Android之Http通信——3.Android(安卓)HTTP请求方式:HttpURLConn
  2. Android中通过scheme实现网页打开App(deep-link)
  3. GVoice腾讯游戏语音Android(安卓)Studio端接入方法
  4. Android(安卓)系统移植与调试(一)Android编译环境编译服务器搭建
  5. 创建Android守护进程实例(底层服务)
  6. 10个Android项目
  7. android http post请求
  8. Android日期时间格式国际化的实现代码
  9. Android通过代码获取ROOT权限

随机推荐

  1. Android(安卓)仿3g体育门户客户端赛事图
  2. EditText在输入法上显示搜索按钮
  3. 2011.09.22——— android ViewStub的简
  4. android常用代码片段
  5. android 不自动弹出虚拟键盘
  6. Android应用程序组件Content Provider的
  7. ubuntu 11.10 搭建 Android(安卓)开发环
  8. android framework
  9. Basic4android (Basic for Android) - Ra
  10. App 权限一点知识