1.Started Service 代码详解
onStartCommand(Intent intent, int flags, int startId)必须实现!在其中启动服务提供的功能。例如,若该服务是在后台下载文件,则在该函数中启动一个新的线程(Thread),在线程中实现下载功能。当客户端通过startService()启动函数时,系统会自动执行服务对应的onStartCommand()函数。
onBind(Intent intent)必须实现!返回null即可。onBind()是"Bound Service"中用到的函数,在"Started Service"服务不会执行onBind();但必须实现它,因为onBind()是Service类的抽象方法。
onCreate()可以不用实现,视用户需求而定。当服务被创建时,系统会自动调用该函数。一般在该函数中进行初始化工作,例如:新建线程。
onDestroy()可以不用实现,视用户需求而定。当服务被销毁时,系统会自动调用该函数。一般在该函数中进行清除工作,例如,终止并回收线程。
3、Activity通过startService()启动服务
4、Activity通过stopService()结束服务
例如:要实现一个activity通过按钮启动一个后台数数服务,再通过按钮结束该服务。
private class ShuShu extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
Log.i("doSomethingThread", i + "");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
要想用后台服务的方式执行上述的线程则在onStartCommand方法中来调用。
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.d("service.onStartCommand()", "onStartCommand");
shuShu.start();
return START_STICKY;
}
结束的话在activity中调用stopService,他会执行service中的onDestory()
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.d("service.onDestroy()", "onDestroy");
if(shuShu!=null){
shuShu.interrupt();
}
super.onDestroy();
}
这里值得一提的是onStartCommand()方法返回的参数:
START_STICKY
如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY
“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT
重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY
START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
2.Bound Service 代码详解
2、 onCreate():可以不用实现,视用户需求而定。当服务被创建时,系统会自动调用该函数。一般在该函数中进行初始化工作,例如:新建线程。
onDestroy():可以不用实现,视用户需求而定。当服务被销毁时,系统会自动调用该函数。一般在该函数中进行清除工作,例如,终止并回收线程。
onBind():必须实现!在onBind()中要返回IBinder对象。IBinder对象的作用是让客户端通过IBinder获取该service的对象,从而调用服务提供相关的功能。Anroid传递数据的机制是基于IBinder的,我们不能直接传递service的对象。总之,我们需要记住的是onBind()中需要返回IBinder对象。下面说说IBinder对象怎么获取。
通常,我们通过在"Bound Service"中创建一个继承于Binder的内部类。在该内部类中添加一个方法,比如getService(),返回“Bound Service”的对象。然后在onBind()中返回该内部类的对象即可。
public class LocalBinder extends Binder {
public MyService getService() {
// Return this instance of LocalService so clients can call public methods
return MyService.this;
}
}
private LocalBinder binder = new LocalBinder();
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return binder;
}
在客户端中创建一个继承于ServiceConnection的内部类;实现ServiceConnection中的两个抽象函数:onServiceConnected() 和 onServiceDisconnected()。 onServiceConnected()在绑定服务成功时会被系统调用,在onServiceConnected()的输入参数包含“onBinder()中返回的IBinder对象”,根据该对象,我们就能获取到service的对象,之后就可调用service提供的服务。 onServiceDisconnected()在解除绑定时会被系统调用。
private ServiceConnection mConnection = new ServiceConnection() {
/**
* 绑定服务成功的回调函数
*/
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
Log.d("MainActivity", "onServiceConnected");
// 获取IBinder服务对象
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
/**
* 解除绑定的回调函数
*/
@Override
public void onServiceDisconnected(ComponentName arg0) {
Log.d("MainActivity", "onServiceDisconnected");
mBound = false;
}
};
在bindService()中传入该内部类的对象即可。
在onServiceConnected()中已经获取到service对象;现在,在我们客户端的任何地方都可以调用到该service提供的服务了。
在Bound Service类中实现以下接口:
3、客户端通过bindService()来绑定服务。bindService()中传递的参数包含一个ServiceConnection对象,下面说说怎么获取该对象。
4、 调用Bound Service提供的服务函数接口,以执行相关操作。
5、客户端通过unbindService()结束服务。