Android 中的应用组件--Service

1.  Service 是什么(What)?

Service是一种在Android应用后台的一种组件,没有自己的界面,不需要与用户交互。

1)Android 中的一个应用组件?(生命周期方法)

2)Android 中的一个后台服务?(可以长时间运行于后台)

最基本的两种用途:执行长时间时间运行的耗时操作,如网络下载,音乐播放,文件系统检测。

一种是组件间的交互(通过将某些功能以Service组件的形式进行封装,然后提供给其他应用组件调用,而不管这些组件是否与Service组件在同一进程中)。

FAQ?

 

1)对于长时间的耗时操作是直接起工作线程,还是启service?

建议:在Service中启工作线程。

 

2)为什么不在activity启工作线程执行耗时操作呢?

 

因为当activity工作于后台处于停止状态时,它所

在进程的生命力就会比较薄弱,在内存不足时可

能会被杀死。

2、Service 与 Thread 的区别

  

很多时候,你可能会问,为什么要用 Service,而不用 Thread 呢,因为用 Thread 是很方便的,比起 Service 也方便多了,下面我详细的来解释一下。

 

1).ThreadThread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作。

2).ServiceService 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上。因此请不要把 Service 理解成线程,它跟线程半毛钱的关系都没有!

  

既然这样,那么我们为什么要用 Service 呢?其实这跟 android 的系统机制有关,我们先拿 Thread 来说。Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被finish 之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。

  

举个例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该Thread 需要在 Activity 没有start的时候也在运行。这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。

  

因此你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。

 

在Android 中的进程可以分为如下几种类型

 

1)前台进程(可见,可以与用户交互)

2)可见进程(可见,但不能与用户交互)

3)服务进程(后台有service在运行)

4)后台进程(没有service组件,所有的activity都处于停止状态)

5)空进程(没有任何组件在运行的进程)

 

以上进程的生命力,从高到低。

 

按运行地点分类:

类别

区别

 优点

缺点 

 应用

本地服务(Local

该服务依附在主进程上,

 服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不需要IPC,也不需要AIDL。相应bindService会方便很多。

 主进程被Kill后,服务便会终止。

 非常常见的应用如:HTC的音乐播放服务,天天动听音乐播放服务。

远程服务(Remote

该服务是独立的进程,

 服务为独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性。

 该服务是独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点。

 一些提供系统服务的Service,这种Service是常驻的。

其实remote服务还是很少见的,并且一般都是系统服务。

按运行类型分类:

类别

区别

应用

前台服务

会在通知一栏显示 ONGOING 的 Notification,

当服务被终止的时候,通知一栏的 Notification 也会消失,这样对于用户有一定的通知作用。常见的如音乐播放服务。

后台服务

默认的服务即为后台服务,即不会在通知一栏显示 ONGOING 的 Notification。

当服务被终止的时候,用户是看不到效果的。某些不需要运行或终止提示的服务,如天气更新,日期同步,邮件同步等。

有同学可能会问,后台服务我们可以自己创建 ONGOING 的 Notification 这样就成为前台服务吗?答案是否定的,前台服务是在做了上述工作之后需要调用 startForeground ( android 2.0 及其以后版本 )或 setForeground (android 2.0 以前的版本)使服务成为 前台服务。这样做的好处在于,当服务被外部强制终止掉的时候,ONGOING 的 Notification 任然会移除掉。

 

按使用方式分类:

类别

区别

startService 启动的服务

主要用于启动一个服务执行后台任务,不进行通信。停止服务使用stopService

bindService 启动的服务

该方法启动的服务要进行通信。停止服务使用unbindService

startService 同时也 bindService 启动的服务

停止服务应同时使用stepService与unbindService

以上面三种方式启动的服务其生命周期也有区别,将在随后给出。

 

2.Android 中的Service 的应用场合?(when,why)

 

执行长时间耗时操作时时,可以考虑在service

组件中执行,例如音乐的播放,股票信息的时

时加载等。

 

记住:并不是耗时都要写到service,短时间的

耗时完全可以在activity中启工作线程执行。

 

Android中Service 的类型?

 

1)  启动模式的Service

如果Service组件是长时间运行的操作,则一般采用启动模式,采用启动模式的Service一般持续执行一个单一的操作,而且并不会向调用者返回任何信息。Service被启动后,将一直处于运行状态,即使调用startService的进程结束了,Service仍然还存在,直到有进程调用stopService,或者Service调用stopSelf自杀。

 

2)  绑定模式的Service

如果Service组件提供一种封装的功能供其他组件使用,则一般采用绑定模式。步骤:通过调用组件对象的bindService方法启动Service对象实例,如果没有指定的Service实例被创建,则该方法调用Service的onCreate()方法来创建一个实例,实例启动后,将调用onBind()方法,onBind方法返回给客户端一个IBinder接口实例,IBinder允许客户端回调Service方法,不如得到Service运行的状态或其他操作。只要连接建立,Service就会一直运行,(不管客户是否保留Service的IBinder的引用)。通常IBinder是一个使用AIDL写成的复杂接口。

 

3)混合模式的Service

 

我们在理解这些模式的service时,需要重点掌握

这些模式service对象的生命期,以及其生命周期

方法,我们可以在对应的生命周期方法中执行业

务。

 

***启动模式的Service

1、启动模式下的Service

实现步骤:1、创建Service类,继承android.app.Service类

2、实现onStartCommand等生命周期方法。

3.在Andridmanifest.xml文件中配置Service组件。

由于Service是在主线程运行的,为避免产生应用无响应异常,必须在Service类的内部创建一个单独的线程,用于耗时的业务逻辑。

Android SDK提供了更好的方法,既IntentService(同时解决了多请求下线程同步的问题)。

 

IntentService:

 

1、在应用的主线程外创建一个单独的工作线程来执行传递到onStartCommand方法的Intent组件。

2、创建一个工作队列,它每次将一个Intent传递到onHandleIntent(),不需要考虑多线程的同步问题。

3、当所有请求被处理完成后,将自动停止服务而不需要显示调用stopSelf方法。

4、提供一个返回null值的onBind方法的默认实现。

5、提供了onStartCommand方法的默认时间,它将所有的Intent发送到一个工作队列,并进一步发送到onHandleInteng方法。

运行模式:

在启动模式下,Service中的业务逻辑主要在onStartCommand方法中实现,每次通过调用方法startService来启动Service,都会调用onStartCommand方法,其中方法的返回值决定了Service的运行模式。

1、START_NOT_STICKY:如果Sevice在启动后,被kill掉,并且没有新启动的Intent传给它,那么将Service移出启动状态并且不重新生成,知道再次显示调用Context.startService。适用场景:网上下载数据。

2、START_REDELIVER_INTENT:如果Service进程在启动后kill掉,那么它将会被重启,并且最后传给他的Intent通过onStartCommand(Intent ,int,int)会被重新传给他,这种模式保证了传给它Intent一定会被处理完毕,适用场景:关键业务处理。

3、START_STICKY:如果Service在它启动后被kill掉,那么Android将让Service继续保持started状态,但是不保留启动它的Intent,Android将重新创建Service实例,并执行onStartCommand方法,如果此时没有新的Intent请求,此时Intent的参数是null,这一点要特别注意。适用场景:后台播放音乐。这种运行模式的特点是需要显示启动并停止Service。

 

启动模式service的启动和关闭

1)通过startService方法启动

2)通过stopService停止,在内部可以通过stopSelf(startId)去停止

 

**启动模式Service对象的生命周期方法:

1)onCreate(service创建时执行)

2)onStartCommand(每次启动都会执行)

3)onDestory(service销毁时会执行)

生命周期

使用context.startService()启动Service是会会经历:

  context.startService()->onCreate()- >onStart()->Service running

context.stopService() | ->onDestroy()->Service stop

context.startService()->onCreate()->onStart()->Servicerunning->context.stopService()-> onDestroy()-> Servicestop 

  如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。

 stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。

 

所以调用startService的生命周期为:onCreate --> onStart(可多次调用) -->onDestroy

 

Serivce 的子类IntentService的应用?

IntentService会默认启动一个工作线程,我们

可以将耗时操作放在onHandleIntent中,此方

法执行结束,service会自动关闭。

 

FAQ?

 

1)启动模式Service 的粘性?(参考onStartCommand方法的返回值)

2)启动模式Service 如何通过隐式Intent启动

a)隐式意图需要在清单配置文件配置intent-filter

 

切记:service不用了,要记得停止。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值