http://android.blog.51cto.com/268543/527314
- 本地服务 Local Service 用于应用程序内部。
它可以启动并运行,直至有人停止了它或它自己停止。在这种方式下,它以调用Context.startService()启动,而以调用Context.stopService()结束。它可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。
用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。 - 远程服务 Remote Service 用于android系统内部的应用程序之间。
它可以通过自己定义并暴露出来的接口进行程序操作。客户端建立一个到服务对象的连接,并通过那个连接来调用服务。连接以调用Context.bindService()方法建立,以调用 Context.unbindService()关闭。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。
可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。
生命周期
看看官方给出的比较流程示意图:

拥有service的进程具有较高的优先级
1.如果service正在调用onCreate,onStartCommand或者onDestory方法,那么用于当前service的进程则变为前台进程以避免被killed。
2.如果当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,但是比那些不可见的进程更重要,这就意味着service一般不会被killed.
3. 如果客户端已经连接到service (bindService),那么拥有Service的进程则拥有最高的优先级,可以认为service是可见的。
4. 如果service可以使用startForeground(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。
2.如果当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,但是比那些不可见的进程更重要,这就意味着service一般不会被killed.
3. 如果客户端已经连接到service (bindService),那么拥有Service的进程则拥有最高的优先级,可以认为service是可见的。
4. 如果service可以使用startForeground(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。
如果有其他的应用组件作为Service,Activity等运行在相同的进程中,那么将会增加该进程的重要性。
本地service
1.不需和Activity交互的本地服务
public
class LocalService
extends Service {
private
static
final String TAG =
"LocalService";
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG,
"onBind");
return
null;
}
@Override
public
void onCreate() {
Log.i(TAG,
"onCreate");
super.onCreate();
}
@Override
public
void onDestroy() {
Log.i(TAG,
"onDestroy");
super.onDestroy();
}
@Override
public
void onStart(Intent intent,
int startId) {
Log.i(TAG,
"onStart");
super.onStart(intent, startId);
}
}
}
Activity:
public
class ServiceActivity
extends Activity {
@Override
protected
void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.servicedemo);
((Button) findViewById(R.id.startLocalService)).setOnClickListener(
new View.OnClickListener(){
@Override
public
void onClick(View view) {
// TODO Auto-generated method stub
startService(new Intent("com.demo.SERVICE_DEMO"));
}
});
((Button) findViewById(R.id.stopLocalService)).setOnClickListener(
new View.OnClickListener(){
@Override
public
void onClick(View view) {
// TODO Auto-generated method stub
stopService(new Intent("com.demo.SERVICE_DEMO"));
}
});
}
}
}
在AndroidManifest.xml添加:
<
service
android:name
=".LocalService"
>
<
intent-filter
>
<
action
android:name
="com.demo.SERVICE_DEMO"
/>
<
category
android:name
="android.intent.category.default"
/>
</
intent-filter
>
</ service >
</ service >
2.本地服务和Activity交互
public class LocalService extends Service {
}
1. 添加了一个public内部类继承Binder,并添加getService方法来返回当前的Service对象;
2. 新建一个IBinder对象——new那个Binder内部类;
3. onBind方法返还那个IBinder对象。
Activity:
public class LocalServiceBinding extends Activity {
}
AndroidManifest.xml里添加:
<
service
android:name
=".app.LocalService"
/>
< activity android:name =".app.LocalServiceBinding" android:label ="@string/activity_local_service_binding" >
<
intent-filter
>
<
action
android:name
="android.intent.action.MAIN"
/>
<
category
android:name
="android.intent.category.SAMPLE_CODE"
/>
</
intent-filter
>
</ activity >
< activity android:name =".app.LocalServiceBinding" android:label ="@string/activity_local_service_binding" >
</ activity >
运行时,发现调用次序是这样的:
bindService:
1.LocalService : onCreate
2.LocalService : onBind
3.Activity: onServiceConnected
2.LocalService : onBind
3.Activity: onServiceConnected
unbindService: 只是调用onDestroy
可见,onStart是不会被调用的,而onServiceDisconnected没有调用的原因在上面代码的注释有说明。
介绍onStartCommand()需要用到的几个常量
(引自官方文档)
START_NOT_STICKY
-
If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver. This is the safest option to avoid running your service when not necessary and when your application can simply restart any unfinished jobs.
START_STICKY
-
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.
START_REDELIVER_INTENT
- If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand() with the last intent that was delivered to the service. Any pending intents are delivered in turn. This is suitable for services that are actively performing a job that should be immediately resumed, such as do wnloading a file.
Running a Service in the Foreground