Android四大组件——service

service不想自己只是会用,充电时间。

任务:startService与BindService区别,IntentService是咋回事。

通过记录轨迹并显示的一个dome来学习service,
框架:GPS+腾讯地图显示+数据库记录当前运动轨迹信息+本地文件记录每次运动信息;
细节:腾讯地图定位当前位置,轨迹分为跑步和骑行,可以记录每次运动并可以看之前运动轨迹。
主要测试:软件记录轨迹过程中通过清除后台运行+重启手机查看service运行状态。


一.腾讯地图显示并定位当前位置;

参考腾讯官方dome改成自己的样式下载。界面如下:
这里写图片描述


二.开打GPS记录轨迹。

分析:由于记录轨迹在APP在后台运行时只要用户没有点击暂停或者停止的时候都要记录GPS的轨迹。


一个service被启动后,实际上还是运行在主线程中,即UI线程。若用户要执行比较耗时的操作,建议新建一个线程来处理;否则可以到UI线程阻塞,影响用户体验。

服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。

生命周期
这里写图片描述

像一个activity那样,一个service有些可以用来改变状态的生命周期方法,但是比activity的方法少,service生命周期方法只有三个public

void onCreate()
void onStart(Intent intent)
void onDestroy()

bindService简介
客户端建立一个与Service的连接,并使用此连接与Service进行通话
通过Context.bindService()方法来绑定服务
Context.unbindService()方法来关闭服务。

可以通过接口被外部程序调用。外部程序建立到service的连接,通过连接来操作service。建立连接调开始于Context.bindService(), 结束于Context.unbindService().

多个客户端可以绑定同一个服务,如果Service还未被启动,bindService()方法可以启动服务。


启动流程

context.bindService() ——> onCreate() ——> onBind() ——> Service running ——> onUnbind() ——> onDestroy() ——> Service stop

onBind()将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的实例、运行状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。

所以调用bindService的生命周期为:onCreate –> onBind(只一次,不可多次绑定) –> onUnbind –> onDestory。

在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。


生命周期

执行bindService时,Service会经历onCreate->onBind。这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。这里所谓的绑定在一起就是说两者共存亡了。


第一次执行bindService时,onCreate和onBind方法会被调用,但是多次执行bindService时,onCreate和onBind方法并不会被多次调用,即并不会多次创建服务和绑定服务。


bindservice的使用场景
通过bindService开启的服务,服务开启之后,调用者和服务之间 还存在着联系 , 一旦调用者挂掉了.service也会跟着挂掉 .

———-

startService简介

通常,一个被启动的服务执行一个单一操作,并且不给调用者返回结果。若需要返回结果,可以通过广播(BroadcastReceiver)来实现。

开始:
Context.startService()

停止:
Context.stopService()
Service.stopSelf()
Service.stopSelfResult()

只要调用一次stopService()方法便可以停止服务,无论之前它被调用了多少次的启动服务方法。

如果没有程序停止它或者它自己停止,service将一直运行。在这种模式下,service开始于调用Context.startService() ,停止于Context.stopService().


生命周期
执行startService时,Service会经历onCreate->onStartCommand。当执行stopService时,直接调用onDestroy方法。调用者如果没有stopService,Service会一直在后台运行,下次调用者再起来仍然可以stopService。


多次调用startService,该Service只能被创建一次,即该Service的onCreate方法只会被调用一次。但是每次调用startService,onStartCommand方法都会被调用。Service的onStart方法在API 5时被废弃,替代它的是onStartCommand方法。


在示例中,我们自定义了onStartCommand()的返回值。Android API文档中说明它的返回值,可以有以下4种:

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后一定能重启。

startservice使用场景
1.通过startservice开启的服务.一旦服务开启, 这个服务和开启他的调用者之间就没有任何的关系了.调用者不可以访问 service里面的方法. 调用者如果被系统回收了或者调用了ondestroy方法, service还会继续存在 。

startService()和bindService()两种模式是完全独立的。你可以绑定一个已经通过startService()方法启动的服务。


既使用startService又使用bindService的情况
如果一个Service又被启动又被绑定,则该Service会一直在后台运行。首先不管如何调用,onCreate始终只会调用一次。对应startService调用多少次,Service的onStart方法便会调用多少次。Service的终止,需要unbindService和stopService同时调用才行。不管startService与bindService的调用顺序,如果先调用unbindService,此时服务不会自动终止,再调用stopService之后,服务才会终止;如果先调用stopService,此时服务也不会终止,而再调用unbindService或者之前调用bindService的Context不存在了(如Activity被finish的时候)之后,服务才会自动停止。

那么,什么情况下既使用startService,又使用bindService呢?

如果你只是想要启动一个后台服务长期进行某项任务,那么使用startService便可以了。如果你还想要与正在运行的Service取得联系,那么有两种方法:一种是使用broadcast,另一种是使用bindService。前者的缺点是如果交流较为频繁,容易造成性能上的问题,而后者则没有这些问题。因此,这种情况就需要startService和bindService一起使用了。

同时实现两种接口,即能提供两种服务。

另外,如果你的服务只是公开一个远程接口,供连接上的客户端(Android的Service是C/S架构)远程调用执行方法,这个时候你可以不让服务一开始就运行,而只是bindService,这样在第一次bindService的时候才会创建服务的实例运行它,这会节约很多系统资源,特别是如果你的服务是远程服务,那么效果会越明显(当然在Servcie创建的是偶会花去一定时间,这点需要注意)。


“Started Service”和“Bound Service”的主要区别:

(01) 启动/停止方式不同:

  • 若要启动“Started
    Service”,需要调用startService();要停止该服务,要调用stopService()或stopSelf()。
  • 若要绑定“Bound Service”,则调用bindService();若要解除绑定,则要调用unbindService()。

(02) 实现接口不同

  • Started
    Service”中,一般要实现service的onStartCommand()接口。因为startService()会调用onStartCommand()接口,我们一般在onStartCommand()中执行一些服务提供的功能,若启动一个线程用于下载。
  • “Bound Service”中,一般要实现service的onBind()接口。
    onBind()函数要返回一个IBinder对象,客户端调用bindService()绑定该服务时被调用。这个绑定是异步的,bindService()方法会立即返回,并且不给客户端返回IBinder对象。要接收IBinder对象,客户端必须创建一个实现ServiceConnection类,并创建ServiceConnection的实例;然后在,bindService()方法中调用ServiceConnection的实例。

(03) 活跃生命周期不同

这里“活跃生命周期”(active lifetime)不同于“完整生命周期”(entire lifetime)。它们的完整生命周期都是起始于onCreat(),结束于onDestroy()。但“活跃生命周期”指的是服务仍然是活动状态。
  • “Started Service”的活跃生命周期开始于startService(),停止于stopService()或stopSelf()。一个“Started Service”可以被多次启动,每次启动都会调用service的onStartCommand()接口;但是,一旦stopService()或stopSelf()被调用,它的活跃生命周期即结束!
  • “Bound Service”的活跃生命周期开始于bindService(),停止于最后一个客户端调用unbindService()。意思是,“Bound Service”可以被多个客户端绑定,即多个客户端可以调用bindService()来绑定相同的服务。当第一个绑定服务的客户端调用bindService()时,“Bound Service”的活跃生命周期即开始了;当所有的客户端全部解除绑定时,它的活跃生命周期即结束了。

综上:采用startService+bindService的方法。同时会对比只用startService 和 bindService的处理结果。


IntentService介绍
IntentService继承与Service,它最大的特点是对服务请求逐个进行处理。当我们要提供的服务不需要同时处理多个请求的时候,可以选择继承IntentService。

IntentService有以下特点:

  1. 它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。
  2. 创建了一个工作队列,来逐个发送intent给onHandleIntent()。
  3. 不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。
  4. 默认实现的onBind()返回null
  5. 默认实现的onStartCommand()的目的是将intent插入到工作队列中。

继承IntentService的类至少要实现两个函数:构造函数和onHandleIntent()函数。要覆盖IntentService的其它函数时,注意要通过super调用父类的对应的函数。

IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。
所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。
用IntentService的好处

  1. 我们省去了在Service中手动开线程的麻烦
  2. 当操作完成时,我们不用手动停止Service
  3. it’s so easy to use!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值