您的位置:首页 > 移动开发 > Android开发

Android学习之服务Service

2015-07-21 17:46 567 查看
服务Service是Android四大组件之一,可以理解为是一个没有界面,在后台运行耗时操作的组件。其他的应用组件可以启动Service,当切换到其他场景是,Service也能够在后台持续运行。一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。

值得一提的是service与activity一样都存在与当前进程的主线程中,所以,一些阻塞UI的操作,比如耗时操作不能放在service里进行,比如另外开启一个线程来处理诸如网络请求的耗时操作。如果在service里进行一些耗CPU和耗时操作,可能会引发ANR警告,这时应用会弹出是强制关闭还是等待的对话框。所以,对service的理解就是和activity平级的,只不过是看不见的,在后台运行的一个组件,这也是为什么和activity同被说为Android的基本组件。

Service有两种启动方式,一种是直接用startService()启动,一种是绑定bindService()启动。其各自的特点如下:

通过startService()启动的服务处于“启动的”状态,一旦启动,service就在后台运行,即使启动它的应用组件已经被销毁了。通常started状态的service执行单任务并且不返回任何结果给启动者。通过调用bindService()来启动,一个绑定的service提供一个允许组件与service交互的接口,可以发送请求、获取返回结果,还可以通过夸进程通信来交互(IPC)。绑定的service只有当应用组件绑定后才能运行,多个组件可以绑定一个service,当调用unbind()方法时,这个service就会被销毁了。

其生命周期如下图所示:



两种启动service的方式以及他们的生命周期,bind service的不同之处在于当绑定的组件销毁后,对应的service也就被kill了。service的声明周期相比与activity的简单了许多,只要好好理解两种启动service方式的异同就行。

service生命周期也涉及一些回调方法,这些方法都不用调用父类方法,具体如下:

<span style="font-size:18px;">public class ExampleService extends Service {
int mStartMode;       // indicates how to behave if the service is killed
IBinder mBinder;      // interface for clients that bind
boolean mAllowRebind; // indicates whether onRebind should be used

@Override
public void onCreate() {
// The service is being created
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The service is starting, due to a call to startService()
return mStartMode;
}
@Override
public IBinder onBind(Intent intent) {
// A client is binding to the service with bindService()
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// All clients have unbound with unbindService()
return mAllowRebind;
}
@Override
public void onRebind(Intent intent) {
// A client is binding to the service with bindService(),
// after onUnbind() has already been called
}
@Override
public void onDestroy() {
// The service is no longer used and is being destroyed
}
}</span>


服务(Service)的停止和启动

1 .如果service是非绑定的,最终当任务完成时,为了节省系统资源,一定要停止service,可以通过stopSelf()来停止,也可以在其他组件中通过stopService()来停止。

绑定的service可以通过onUnBind()来停止service。

2. 有了 Service 类我们如何启动他呢,有两种方法:

•Context.startService() •Context.bindService()

1). 在同一个应用任何地方调用startService() 方法就能启动Service 了,然后系统会回调Service 类的 onCreate() 以及 onStartCommand() 方法。这样启动的Service 会一直运行在后台,直到Context.stopService() 或者 StopSelf() 方法被调用。另外如果一个Service 已经被启动,其他代码再试图调用startService() 方法,是不会执行onCreate() 的,但会重新执行一次onStartCommand()


2). 另外一种 bindService() 方法的意思是,把这个Service 和调用 Service 的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方法你可以从这里返回一个实现了 IBind 接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service 还没有运行,使用这个方法启动 Service 就会
onCreate() 方法而不会调用 的onStartCommand()。

3.总结:

1). startService()的目的是回调的onStartCommand方法,onCreate() 方法是在Service不存在的时候调用的,如果Service存在(例如之前调用了bindService,那么Service的onCreate方法已经调用了)那么startService()将跳过onCreate() 方法。

2). bindService()目的是回调onBind()方法,它的作用是在Service和调用者之间建立一个桥梁,并不负责更多的工作(例如一个Service需要连接服务器的操作),一般使用bindService来绑定到一个现有的Service(即通过StartService启动的服务)。

由于Service 的onStartCommand()方法只有在startService()启动Service的情况下才调用,故使用的onStartCommand()的时候要注意这点。

4. 与 Service 通信并且让它持续运行

如果我们想保持和Service 的通信,又不想让Service 随着 Activity 退出而退出呢?你可以先startService() 然后再 bindService() 。当你不需要绑定的时候就执行unbindService() 方法,执行这个方法只会触发Service 的 onUnbind() 而不会把这个 Service 销毁。这样就可以既保持和 Service 的通信,也不会随着 Activity 销毁而销毁了。

IntentService,首先看下官方文档的说明:IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。而在一般的继承Service里面如果要进行耗时操作就必须另开线程,但是使用IntentService就可以直接在里面进行耗时操作,因为默认实现了一个worker
thread。对于异步的startService请求,IntentService会处理完成一个之后再处理第二个。

看下IntentService的具体实现:

<span style="font-size:18px;">public class HelloIntentService extends IntentService {

/**
* A constructor is required, and must call the super IntentService(String)
* constructor with a name for the worker thread.
*/
public HelloIntentService() {
super("HelloIntentService");
}

/**
* The IntentService calls this method from the default worker thread with
* the intent that started the service. When this method returns, IntentService
* stops the service, as appropriate.
*/
@Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
}
}</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: