Android四大组件之一,能在后台执行需要长时间运行并且不需要用户界面的的任务。最常见就是播放音乐了。
通过startService()方法启动的Service被称为Started Service。
一旦启动,即使启动它的组件比如是Activity销毁了,它依然会在后台运行。
用途:常用于执行单个操作,并且不需要返回结果,比如通过网络下载或是上传文件,当执行完毕之后,自己结束自己。
通过调用bindService()方法启动的Service我们就称为Bound Service。
这种服务会提供一个客户端服务端接口,允许启动它的组件与之交互(发送请求、得到结果,甚至可以进程间通信)。
一旦跟Activity绑定,启动之后,就会跟着Activity同生共死,除非被unBind,当然也可以被多个组件同时绑定,这些组件都unBind,它才会销毁。
默认启动方式,运行在主进程中的主线程中。
可配置service的process属性为”:remote”,系统会新建一个进程去运行服务。
实现在framework层的服务就叫做Android Service,用java编写的,也称为Java Service。
实现在Android Runtime中的服务叫Native Service, 又可叫System Service。
常用的分类还是started和bound这两种类型,当然,你可以同时使用
这两种类型,你可以started,也允许你bind。
这两种服务也是有区别的
Started Service一旦通过starService()方法启动,除非你通过stopService()或者stopSelf()去停止,它会一直运行下去直到被系统kill掉,即使启动它的组件被销毁。
bound就不一样了,启动它的组件销毁,它也跟随着一并销毁。
Started Service被starService()方法启动后,如果再次调用startService(),里面的onStartCommand()方法也会跟着执行。
而bound多次执行bindService(),里面的 onBind() 方法不会重复调用。
这也是本质区别,bound常用于进程间通信,也就是远程对象访问。
明确一个条件:交互!
如果要执行在非主线程,但是需要一直跟应用进行交互,这种情况下肯定优先选择Thread。
比如官网的举的例子:你需要播放音乐,同时需要你的Activity也在运行,这时候请还是选择Thread。
我们需要新建一个类,并继承于Service。
在此类中,需要重写父类的几个重要方法:
onCreate(): 服务在第一次创建时调用,如果已经运行,不会重复调用。
onStartCommand(): 当组件调用startService() 一次,次方法就会执行一次,可以多次调用。
onBind(): 组件调用bindSercive()时执行此方法,一般用于进程间通信,返回Binder对象,客户端可通过返回的Binder,获取到服务对象,进一步调用服务里的变量和方法。
onDestroy(): 当服务不再需要时(stopService()、unBindService()或者跟它bind的组件销毁时)调用次方法,常在里面加上释放资源代码。
... >
...
... >
".MyService" />
...
如上代码所示,跟Activity组件声明方式差不多。
如果此服务只允许应用内部启动,需要加上”android:exported=”false”“。
组件通过Intent去启动服务,如下:
Intent intent = new Intent(this, MyService.class);
startService(intent); // 启动started service
bindService(intent, conn, BIND_AUTO_CREATE); // 启动bound service
如果是started service,在启动它的组件里停止,通过stopService()方法,也可以是服务本身通过stopSelf()方法自己停止自己。
要是bound service,使用unbindService()。
started service跟bound service生命周期还是有差异的,请看官网提供的图,如下:
具体方法:
public class MyService extends Service {
@Override
public void onCreate() {
// service被创建时调用
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// service正在运行,每调用一次startService(),此方法就执行一次
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// 有客户端通过bindService()方法绑定到此服务时调用
return null;
}
@Override
public boolean onUnbind(Intent intent) {
// 所有客户端通过unbindService()解绑时调用
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
// 如果某个客户端调用了unbindService(),再次调用bindService()时执行,要求此服务不止被一个客户端同时绑定
super.onRebind(intent);
}
@Override
public void onDestroy() {
// service不再需要,释放资源
super.onDestroy();
}
}
Intent Service属于Stared Service,并且在它基础之上进行了改良,为了适应一些特殊的场合。
Intent Service会开启一个新线程去执行任务,而Started Service默认是执行在UI线程中的;
Intent Service执行完任务之后,会自动调用stopSelf() 停止自己,Started Service则不会,需要手动停止服务;
引用官网的示例代码:
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.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
}
}
可以看到,很简单,只需要重载两个方法即可,一个是构造方法,一个是onHandleIntent。
如果需要重载其他方法,比如onCreate(),别忘了调用父类的实现。