文章目录
Service概要
Service是Android用于在后台运行程序的解决方法,适用于那些不需要与用户交互但却需要持续运行的任务。
Service中的运行不依赖于应用,即使我们程序被切换到后台,或者打开了另一个应用,我们的服务仍然在运行。但当应用被杀死后,所依赖于该应用的服务也会相应销毁。
Service默认运行在主线程,所以不要在Service中执行耗时的操作,除非手动开启子线程。
Service的生命周期
不同的启动Service有两种不同的生命周期。
未绑定的Service:当使用Context.startService
方法开启服务时,会调用onStartCommand
方法,如果Service没有创建,则会先调用onCreate
方法,再调用onStartCommand
方法。此时Service一直处于开启状态,只有当调用stopService
方法或stopself
方法,服务才会停止并调用onDestory
方法。值得注意的是,我们可以多次startService,但是Service只会创建一个实例
绑定的Service:当Activity使用bindService
方法时会将Service与Activity绑定。之后会调用Service的onBind
方法,返回一个Binder用于给Activity调用Service中的方法。如果Service没有被创建,则会先调用onCreate
方法先创建,之后在调用onBind
方法。此时Service和Acitivity处于绑定状态,只有当Activity调用unbindService
方法之后,才会继续调用Service的unbind
方法,最后调用onDestory
方法终止服务。
注意,这两种启动方法并不冲突,当使用startService()启动Service之后,还可再使用bindService()绑定,只不过需要同时调用 stopService()和 unbindService()方法才能让服务销毁掉。
Service的使用
普通Service
第一步新建Service类,必须重写onBind方法,可以选择性的重写onCreate
、onStartCommand
、onDestory
方法。
第二步在AndroidManifest中注册Service。
第三步在Activity中创建Intent,传入当前Activity与Service类,调用startService
方法并传入intent,开启服务。在需要停止服务时,也需要创建Intent,传入当前Activity与Service类,并调用stopService
或stopself
方法传入intent,停止服务。
前台Service
前台服务与普通服务的差别在于,前者会一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。使用前台服务或者为了防止服务被回收掉,比如说我的天气项目中,就有一个天气的通知,就是一个前台服务。可以显示天气信息。
使用前台服务较为简单,在Service类的onStartCommand中创建一个Notification,并正常添加图标,文字等等,不需要使用NotificationManager,而是使用startForeground()方法,将该服务变成前台服务。
系统Service
系统Service比较多,比如的NotificationManager。通过getSyetemService()
方法并传入一个Name就可以得到相应的服务对象了
IntentService
为了可以简单地创建一个异步的、会自动停止的服务,Android 专门提供了一个IntentService类,可以简单认为做了如下图的工作。在onStartCommand中新建一个线程,并在run函数中处理具体的逻辑并调用stopSelf方法,以结束服务。
其使用步骤与普通Service相似。
第一步:新建IntentService类,其区别主要为以下两点。
1.必须构造一个无参构造函数,然后在该函数中调用父类有参数构造函数,并传入当前类的名称;
2.必须重写onHandleIntent方法,在其中可以执行耗时操作,因为在这里已经开了新线程。
第二步:在配置文件中进行注册。
第三步:在活动中利用Intent实现IntentService的启动,和Service用的方法是完全一样的。
Service与Activity的通信
Service可以通过onBind方法与Activity通信。具体流程如下:
1.新创建一个DownloadBinder类继承于Binder,同时在onBind中返回DownloadBinder的实例。
ublic class MyService extends Service {
private DownloadBinder mBinder=new DownloadBinder();
class DownloadBinder extends Binder {
public void startDownload(){
Log.d("MyService","startDownload executed");
}
public int getProgress(){
Log.d("MyService","getProgress executed");
return 0;
}
}
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
2.在Activity中,我们要创建一个ServiceConnection对象,创建该对象需要重写onServiceConnected
方法和onServiceDisconnected
,分别是Service与Activity绑定成功与绑定失败后会回调的方法。onServiceConnected
方法中会返回一个Binder对象。我们将其转为DownloadBinder类型的Binder,并调用其方法。
private MyService.DownloadBinder downloadBinder;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
downloadBinder = (MyService.DownloadBinder) service;
downloadBinder.startDownload();
downloadBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
3.我们需要构造Intent对象,并传入当前Acitivity与我们的Service类。调用bindService
方法,传入Intent对象,传入ServiceConnection对象,并传入一个标志位。这样就将Service与Activity进行了绑定。当我们想取消绑定时,调用unbindService
方法。
case R.id.bind :
Intent bindInent = new Intent(this,MyService.class);
bindService(bindInent,serviceConnection,BIND_AUTO_CREATE);
break;
case R.id.unbind:
unbindService(serviceConnection);
break;
总结(复习必看)
1.Service概述
1.Service是Android用来在后台运行程序的解决方法,适用于那些不需要与用户交互但是需要长期运行的程序。Service只要开启后,不论将应用放到后台还是打开了其他应用,Service都会一直运行。当应用被杀死后,随之关联的Service才会销毁。
2.Service的生命周期
(1)onCreate方法:服务第一次被创建时调用;
(2)onStartCommand方法:服务启动时会调用(调用startService方法会回调的方法);
(3)onBind方法:当服务与Service绑定时,会回调的方法;
(4)onUnBind方法:当服务与Service解绑时,会回调的方法;
(5)onDestory方法:当Service销毁(停止)时回调的方法。
3.Service两种启动方式
(1)未绑定的方式:
当其他组件调用Context的startService方法后,会调用Service的onStartCommand方法,如果Service没有创建,则会先调用onCreate方法,之后再调用onStartCommand方法。此时服务处于开启状态,直到调用了stopService方法或stopSelf方法后,会调用onDestory方法来销毁服务。我们可以多次使用startService方法,但Service的实例只会有一个。
(2)绑定的方式:
当其他组件调用Context的bindService方法后,会回调Service的onBind方法,如果Service没有被创建会先调用onCreate方法,此时服务与组件处于绑定状态,组件可以通过onBind方法返回的Binder对象与Service通信。当组件调用了unbindService方法后,会回调Service的unbind方法,解除绑定,之后会调用onDestory方法停止服务。
以上两种方式并不冲突,当我们使用startService后再调用bindService方法也是可以的,但如果我们想要停止Service的话,需要调用stopService与unbindService。
4.Service与Activity的通信
Service可以通过onBind方法与Acitivity通信。
首先需要在自定义的Service类中创建一个自定义的Binder类,类中可以有一些供Activity使用的方法,在onBind方法中返回自定义Binder的实例。
在Activity中创建一个ServiceConnection的实例,并重写其中的onServiceconnected与onServiceDisconnected方法,在onServiceconnected方法中获取Service传来的Binder对象,并进行操作。
最后创建Intent对象并传入Activity与Service类,之后调用bindService方法传入intent对象,Serviceconnection对象,以及一个标志符,以完成绑定。当我们想断开绑定时,调用unbindService方法,并传入ServiceConnection对象。
5.普通Service与前台Service的使用
普通Service的使用步骤如下:
1.创建Service类,重写onBind方法,选择性重写onCreate、onDestory、onCommand方法
2.在AndroidManifest中注册Service(如果是new 的是已经注册好的)
3.在Acitvity中创建Intent对象,并传入Acitivity与Service类,并通过使用startService并传入Intent对象,以开启服务。如果想要停止服务,也需要创建Intent对象,传入Activity与Service类,并通过使用stopService方法以停止服务。
前台Service的区别于使用步骤如下:
前台Service与普通服务的区别在于,他是一直显示在前台的状态栏处,下拉会显示详细的信息。可以用来天气APP显示天气。
使用方法是在Service的onStartCommand方法中,创建一个Notification,不需要NotifiactionManager而是直接通过startForeground方法开启一个前台服务。
6.是否可以在Service使用耗时操作,如果需要的话怎么办?
Service默认是在主线程的,所以不建议使用耗时操作。如果想要使用耗时操作可以使用IntentService。IntentService做的工作类似于在onStartCommand中开启了新线程,然后在线程中进行耗时操作,执行结束在调用stopself方法。
IntentService的使用方法与Service相似,区别在于创建IntentService时,(1)一定要有一个无参构造函数,并在其中回调父类的有参构造函数并传入当前类的名字。(2)必须重写onHandleIntent方法,在其中可以执行耗时操作,因为在这里已经开了新线程
7.如何保证Service不被杀死?
(1)可以在Service的onDestory中发送广播,广播接收器接收到广播后在onRecive中继续启动Service。
(2)可以在Service的onStartCommand中设置flages值为START_STICKY,让Service调用onDestory之后接着启动
(3)将Service的优先级提高,比如变成前台Service。