文章出处:http://blog.csdn.net/scarthr/article/details/41940357
当一个应用需要持续在后台启动运行并且不怎么需要界面的时候,例如qq后台监听收发消息、音乐后台循环播放等,Service便是最佳人选。今天就来介绍一下Android另一大核心内容——Service。
一 创建Service
Service的生命周期比较简单,看下面这张图可以说明:
一共有两种方法实现Service。
1. 创建启动Service
新建一个类,继承Service,创建Intent指定好需要启动的Servcie,调用startService(Intent intent)即可:
Intent service = new Intent(this, MyService.class);
startService(service);
调用
stopService(service);
来关闭服务(调用Service的onDestroy方法)。
2. 绑定Service
首先要使Activity自己实现ServiceConnection接口或者创建一个实现ServiceConnection接口的类:
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// 服务成功绑定后会执行这个方法
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 服务崩溃时会执行这个方法
}
};
然后创建MyService类继承Service类,复写onBind方法:
@Override
public IBinder onBind(Intent intent) {
return null;
}
如果这个方法返回null的话,将不会成功绑定服务,此处必须返回一个IBinder对象。于是我们使用Android系统提供的Binder类,Binder类已经实现了IBinder接口,我们继承它创建ServiceBinder类:
public class ServiceBinder extends Binder {
}
并在MyService类中声明:
private final ServiceBinder binder = new ServiceBinder();</span>
这样,我们在onBind方法中返回我们创建的这个ServiceBinder就可以了,上述onBind方法修改为:
@Override
public IBinder onBind(Intent intent) {
return binder;
}
最后在Activity中执行
bindService(service, connection, Context.BIND_AUTO_CREATE);
就成功绑将我们的MyService绑定在了Activity上,调用
unbindService(connection);
来解除绑定(关闭服务)。
3. 启动服务和绑定服务的区别
用第一种方法启动的服务在Activity关闭后,仍可以运行,除非我们调用stopService才可以关闭服务(或从Android服务中禁止掉)。
用第二种方法绑定的服务于Activity共存亡,只要Activity关闭,服务就停止。
还有一点需要注意的是:如果一个服务是先用startService启动后调用bindService绑定,那么会先后执行onCreate()和onBind()方法,此时调用unbindService不会触发Service的onDestroy方法,必须再次调用stopService才可以终止服务;要是服务直接用bindService绑定,会执行onCreate()和onBind()方法,再调用unbindService就会触发onDestroy方法(关闭服务)。
那我们为什么要用绑定服务呢?如果我们需要与服务进行通信等操作是,需要时用绑定服务而不是启动服务。我们看下面这个例子:
package com.buzzly.adapter;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class MyService extends Service {
private Timer timer;
private TimerTask task;
private int number = 0;
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public void onCreate() {
startTimer();
super.onCreate();
}
public void startTimer() {
if (timer == null) {
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
number++;
System.out.println(number);
}
};
timer.schedule(task, 1000, 1000);
}
}
public void stopTimer() {
if (timer != null) {
task.cancel();
timer.cancel();
task = null;
timer = null;
}
}
public int getCurrentNumber() {
return number;
}
/**
* 服务绑定器
*/
private final ServiceBinder binder = new ServiceBinder();
public class ServiceBinder extends Binder {
public MyService getServcie() {
return MyService.this;
}
}
}
我们创建一个Timser和TimerTask,在绑定服务的时候调用startTimer方法,每隔一秒钟number加一,在ServiceBinder类中提供getService()方法返回当前服务类实例。然后来看Activity类:
package com.buzzly.adapter;
import android.R;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
public class MyActivity extends Activity {
MyService myService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent service = new Intent(this, MyService.class);
bindService(service, connection, Context.BIND_AUTO_CREATE);
}
public void click(View v) {
int number = myService.getCurrentNumber();
System.out.println(number);
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
myService = ((MyService.ServiceBinder) binder).getServcie();
}
};
}
在bindService时,我们获得了MyService实例,并在点击按钮的时候可以随时获取到MyService类中的number数字。
那么问题就来了,我们费了半天劲,仅仅是获得到了一个MyService实例,难道就不能直接new出来一个吗?答案是否定的,Android系统是不允许我们私自new服务类的,我们只能沟通过启动或者绑定服务类来请求系统创建一个服务类,我们在用绑定方法后可以获取到服务实例,于是接下来我们就用这个实例对象可以想做什么就做什么了。