Android Service

Android Service

Service 是一种运行在后台没有界面的组件,可以执行一些需要长期运行的过程。

需要注意的是,service组件本身并不会新建一个进程或者线程来执行任务,service组件运行在它所属App的主线程中。因此,通常需要在service组件中新建一个线程来执行耗时的任务。

Service 与 new Thread的区别

Service 组件用于当用户没有与app进行交互时在后台执行一些操作,而在Activity中new Thread执行操作需要考虑Activity的生命周期,对于只在与用户交互时才执行的耗时操作应该采用new Thread的方式。

Service可以分为两种类型:

  • started service

started service由其他组件调用startService()方法来启动,一经启动便会一直运行下去,直到有其他某个组件调用stopService()方法请求停止或者该service组件自己调用stopSelf()方法终止自己的运行。

started service通常用于执行一些不需要返回结果的操作,操作执行完成之后自己调用stopSelf()方法结束。

  • bound service

bound service由其他组件调用bindService()方法来启动,一个bound service可以被多个组件bind,bind该service的组件可以通过调用unbind()方法结束与service的通信,当bind该bound service的所有组件都结束了与它之间的通信,该bound service的生命周期也就随之结束。

bound service通常用于需要返回执行结果或者执行过程中需要进行交互的操作,其他组件可以通过IBinder或者Messenger与bound service进行通信。

started service 与 bound service之间并没有十分明显的界限,在实现上的区别只体现在是否实现相关的回调函数,started service主要实现onStartCommand()方法,bound service主要实现onBind()方法和onUnbind()方法。

创建Service组件

  • 从Service类或者其子类IntentService类继承,定义Service组件的实现类。

  IntentService类是Service类的子类,它使用一个worker线程和一个队列处理所有Intent请求,只需覆盖实现其onHandleIntent()方法来处理一个Intent请求,当所有的Intent请求都处理完后,IntentService会自动结束运行,无需使用者调用stopSelf()方法来结束。
  Service类则更为灵活,可以自定义使用单线程或者多个线程对Intent请求进行处理。

  • 像Activity一样,需要在AndroidManifest.xml文件中声明Service组件。

Service的生命周期

  • started service

    onCreate(),创建Service组件时回调,只被调用一次。

    onStartCommand(),其他组件调用startService()方法请求启动Service组件时回调该方法。

    该Service组件调用stopSelf()方法或者其他组件调用stopService()方法。

    onDestroy(),该Service组件的生命周期即将结束时回调,可以在该方法中做一些资源的回收工作。

  • bound service

    onCreate(),创建Service组件时回调。

    onBind(),其他组件调用bindService()方法请求bind到该Service组件时回调该方法。

    onUnbind(),所有其他组件都解除与该Service的bind后回调该方法。

    onDestroy(),该Service的生命周期即将结束。

  • 如前所述,started service和bound service之间的界限不明显。 如果bound service组件也实现了onStartCommand()方法,那么就可以接收startService()方法的intent请求,它的生命周期在onUnbind()方法之后不会直接进入onDestroy,而是需要调用stopSelf()方法或者stopService()方法来结束其生命周期。

  • 当系统发现内存资源不够用时,可能会主动kill掉还在运行的Service组件。Service组件可以通过调用startForeground()方法来将自己设置成foreground模式,处于foreground模式的Service组件不会被系统主动kill掉。

Bound Service的实现步骤

  • 继承Binder类

bound service组件实现onBind()方法,返回IBinder接口对象。IBinder接口中定义了其他组件与bound service组件进行通信的方法接口,可以通过继承Binder类来实现IBinder接口。

其他组件在调用bindService()方法时需要提供ServiceConnection对象,ServiceConnection对象中包含一个回调方法onServiceConnected(),当bound service组件成功与之建立连接后,会回调onServiceConnected方法返回IBinder接口对象。

这种方式适用于bound service组件只会被同一个app中的其他组件使用,因为IBinder需要将与Service组件通信的方法接口暴露给其他组件,只有Service组件和其他组件运行在同一个虚拟机(即同一个进程)中才可以。

  • 使用Messenger类

bound service组件中实现一个Handler接口,在Handler接口的handleMessage()方法中根据消息类型来处理来自其他组件的请求。bound service组件还持有一个Messenger对象,该Messenger对象持有Handler的引用,并且在onBind()方法中返回的IBinder对象也是由该Messenger对象创建的。

其他组件也持有一个Messenger对象,该Messenger对象根据ServiceConnection对象中返回的IBinder对象构造而来。其他组件可以通过该Messenger对象的send()方法向Service组件发送指定消息类型的Message信息。

这种方式向其他组件屏蔽了IBinder接口的具体通信方法,而是根据双方约定好的消息类型通过Messenger对象来进行通信。可以用于Service组件与其他组件之间的跨进程通信。

  • AIDL

Messenger类是基于AIDL的方式实现的,Messenger类会使用队列来保存其他组件发来的消息,使用单个工作线程,每次只提供一个消息给Handler对象处理。

如果需要Service组件拥有同时处理多个消息的能力,则需要使用AIDL的方式来实现。

posted @ 2016-06-17 19:09  jqc  阅读(203)  评论(0编辑  收藏  举报