Android系统也提供了一种称为“Service”的组件通常在后台运行。Activity 可以用来启动一个Service,Service启动后可以保持在后台一直运行,即使启动它的Activity退出或是切换到别的应用Service也能保持运行状态。

Service 可以以两种形式存在:

  • Started 当一个如Activity使用startService()来启动一个Service,一旦Service启动后,就不受启动它的Activity控制, 可以在后台长期运行,通常这种Service在后台执行某个费时操作(如下载文件)不会向启动它的Activity返回结果。
  • Bound 为Activity或是其它程序部件使用bindService()来启动Service。Bound Service提供了一种Client/Service方法允许调用Service的Activity与Service进行交互:发送请求,取得结果,并 支持进程间通信。 一般Bound Service的生命周期和启动它的Activity相同,多个Activity可以同时绑定一个Service。 当所有Activity 都断开与Service之间的绑定时。Service自动结束。

虽然Service可以有上述两种表现形式,这只是为了说明上的方便,实际上同一个Service可以同时以两种方式存在,只要实现两种方法所定义的接口函数就可以了。

创建一个Service,首先需要定义一个Service的子类,然后根据需要重载Service定义的一些核心方法:

  • onStartCommand() 当一个Activity调用startService时,Android系统会调用Service的onStartCommand()方法, 前面说过使用startService启动的Service会在后台长期运行,不受启动它的Activity控制,因此应用程序有责任来停止 Service,Service也可以调用stopSelf来停止自身。
  • onBind() 当一个Activity 使用bindService()来绑定Service时Android系统会调用Service的onBind方法,onBind需要返回一个IBind 对象给调用者(Client)。Client然后可以使用IBind提供的方法来使用Service。
  • onCreate() Service第一次创建时被调用,和Activity的onCreate类似。
  • onDestroy() Service退出时调用。

定义了Service类和实现相应方法后,和Activity一样,也需要在AndroidManifest.xml中定义这个Service:

<manifest … >

<application … >
<service android:name=”.ExampleService” />

< /application>
< /manifest>

和Activity一样,也可以为Service定义Intent Filter,如果你不想共享这个Service,可以将android:exported属性定义为false。

通常情况下Service在后台运行,当Android也支持Service运行在前台,运行在前台的Service必须在屏幕顶端的Status Bar提供一个Notification以提示用户有Service在运行。比如提供个Media Player使用的Service运行在前台,而在标题栏显示当前曲目。

本例Foreground Service Controller就显示了一个在前台运行的Service, 前台运行的Service可以通过调用startForeground()使Service在前台运行。stopForeground停止前台运行,但 Service本身不会停止。 startForeground,stopForeground是从2.0开始支持的,之前的版本采用setForeground。

本例为了支持2.0之前和2.0之后的版本,采用了Reflection的方法来来查找当前版本是否含有startForeground和stopForeground,如果有则调用,没有则还是使用setForeground。

如果找到的话,以下的变量用来存储startForeground和stopForeground方法。和本例Service不相关,就不详述了。 只要知道startForegroundCompat 和stopForegroundCompat的功能就是startForeground 和stopForeground就行了。

private static final Class[] mStartForegroundSignature = new Class[] {
int.class, Notification.class};
private static final Class[] mStopForegroundSignature = new Class[] {
boolean.class}; private Method mStartForeground;
private Method mStopForeground;
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];

下面来看看ForegroundService的代码:
首先是必须作为Service的子类:

public class ForegroundService extends Service

因为是作为“Started” Service来设计的,因此需定义onStartCommand ,同样onStartCommand也是在Android 2.0之后添加的,2.0之前为onStart。本例为了支持所有版本,两个方法对实现了,对应2.0之后的版本,只会调用 onStartCommand,2.0之前的只会调用onStart:

// This is the old onStart method that
// will be called on the pre-2.0 platform.
// On 2.0 or later we override onStartCommand() so this
// method will not be called.
@Override
public void onStart(Intent intent, int startId) {
handleCommand(intent);
} @Override
public int onStartCommand(Intent intent,
int flags, int startId) {
handleCommand(intent);
// We want this service to
//continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}

onStartCommand 可以有返回结果,这个返回值告诉Android系统当这个Service被Kill之后(比如当系统内存不足时)后续操作。START_STICKY 表示系统Kill这个Service之后,如果重新创建这个Service时在调用onStartCommand ,不会将最后的Intent作为参数传入,也就是说intent=null. START_REDELIVER_INTENT则会传入被杀前未处理的最后一个Intent。

本Service不作为Bind Service ,因此通过一个空实现:

@Override
public IBinder onBind(Intent intent) {
  return null;
}

最后看看如何启动/停止这个Service, Controller 是作为这个Service的控制类来实现的,提供了前台启动,后台启动,和停止Service操作:

private OnClickListener mForegroundListener
= new OnClickListener() {
public void onClick(View v) {
Intent intent
= new Intent(ForegroundService.ACTION_FOREGROUND);
intent.setClass(Controller.this,
ForegroundService.class);
startService(intent);
}
}; private OnClickListener mBackgroundListener
= new OnClickListener() {
public void onClick(View v) {
Intent intent
= new Intent(ForegroundService.ACTION_BACKGROUND);
intent.setClass(Controller.this,
ForegroundService.class);
startService(intent);
}
}; private OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v) {
stopService(new Intent(Controller.this,
ForegroundService.class));
}
};

【起航计划 033】2015 起航计划 Android APIDemo的魔鬼步伐 32 App->Service->Foreground Service Controller service使用,共享service,前台服务,onStartCommand的更多相关文章

  1. 【起航计划 002】2015 起航计划 Android APIDemo的魔鬼步伐 01

    本文链接:[起航计划 002]2015 起航计划 Android APIDemo的魔鬼步伐 01 参考链接:http://blog.csdn.net/column/details/mapdigitap ...

  2. 【起航计划 037】2015 起航计划 Android APIDemo的魔鬼步伐 36 App->Service->Remote Service Binding AIDL实现不同进程间调用服务接口 kill 进程

    本例和下个例子Remote Service Controller 涉及到的文件有RemoteService.java ,IRemoteService.aidl, IRemoteServiceCallb ...

  3. 【起航计划 031】2015 起航计划 Android APIDemo的魔鬼步伐 30 App->Preferences->Advanced preferences 自定义preference OnPreferenceChangeListener

    前篇文章Android ApiDemo示例解析(31):App->Preferences->Launching preferences 中用到了Advanced preferences 中 ...

  4. 【起航计划 027】2015 起航计划 Android APIDemo的魔鬼步伐 26 App->Preferences->Preferences from XML 偏好设置界面

    我们在前面的例子Android ApiDemo示例解析(9):App->Activity->Persistent State 介绍了可以使用Shared Preferences来存储一些状 ...

  5. 【起航计划 020】2015 起航计划 Android APIDemo的魔鬼步伐 19 App->Dialog Dialog样式

    这个例子的主Activity定义在AlertDialogSamples.java 主要用来介绍类AlertDialog的用法,AlertDialog提供的功能是多样的: 显示消息给用户,并可提供一到三 ...

  6. 【起航计划 012】2015 起航计划 Android APIDemo的魔鬼步伐 11 App->Activity->Save & Restore State onSaveInstanceState onRestoreInstanceState

    Save & Restore State与之前的例子Android ApiDemo示例解析(9):App->Activity->Persistent State 实现的UI类似,但 ...

  7. 【起航计划 035】2015 起航计划 Android APIDemo的魔鬼步伐 34 App->Service->Local Service Controller

    Local Service Controller 是将LocalService当作“Started”Service来使用,相对于”Bound” Service 来说,这种模式用法要简单得多,Local ...

  8. 【起航计划 034】2015 起航计划 Android APIDemo的魔鬼步伐 33 App->Service->Local Service Binding 绑定服务 ServiceConnection Binder

    本例和下列Local Service Controller 的Activity代码都定义在LocalServiceActivities.Java 中,作为LocalServiceActivities ...

  9. 【起航计划 003】2015 起航计划 Android APIDemo的魔鬼步伐 02 SimpleAdapter,ListActivity,PackageManager参考

    01 API Demos ApiDemos 详细介绍了Android平台主要的 API,android 5.0主要包括下图几个大类,涵盖了数百api示例:

随机推荐

  1. Python之freshman02

    内置方法:https://docs.python.org/3/library/functions.html?highlight=built#abs 一.数学运算 1.abs()-取绝对值 2.divm ...

  2. python安装环境配置、python模块添加、sublime text编辑器配置

    前提: 本文讲述的是  windows环境 python相应的安装配置. 进入官网找安装包,官网地址如下:https://www.python.org/downloads/ 找到相应2.7.x或3.x ...

  3. C++_新特性1-类型转换运算符

    C++的创始人认为C语言的类型转换运算符太过于松散.他采取了更加严格的限制允许的类型转换.并添加了4个类型转换运算符. 这部分特性比较高阶,我把它归于奇技淫巧的范畴.这里简单介绍一下,以后实际有用到再 ...

  4. HDU - 1285-确定比赛名次(拓扑排序+优先队列)

    有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道 ...

  5. Week 5: Object Oriented Programming 9. Classes and Inheritance Exercise: int set

    class intSet(object): """An intSet is a set of integers The value is represented by a ...

  6. 109th LeetCode Weekly Contest Knight Dialer

    A chess knight can move as indicated in the chess diagram below:  .            This time, we place o ...

  7. Notepad++中F3直接搜索选中文字

    用了Notepad++好久了,一直被"F3不能直接搜索选中文字"困扰.毕竟以前习惯UltraEdit的这种操作,很便捷.今天突然发现原来Notepad++快捷键里可以修改这个功能, ...

  8. 【研究】Struts2-052漏洞

    漏洞描述: CVE-2017-9805 2017年9月5日,Apache Struts官方发布最新的安全公告称,Apache Struts 2.5.x的REST插件存在远程代码执行高危漏洞,漏洞编号为 ...

  9. PIE SDK应用掩膜

    1.算法功能简介 当对一幅图像应用掩膜时, 1 值的区域被保留, 0 值的区域被舍弃( 1 值区域被处理, 0 值区域被屏蔽不参与计算). PIE SDK支持算法功能的执行,下面对应用掩膜算法功能进行 ...

  10. 文献综述九:Oracle数据库性能模型的研究

    一.基本信息 标题:Oracle数据库性能模型的研究 时间:2018 出版源:数字技术与应用 文件分类:对框架的研究 二.研究背景 帮助运维人员分析数据库性能,发现问题,指导调优. 三.具体内容 文献 ...