首页 > 代码库 > Services学习(一)

Services学习(一)

  对于需要长期运行,例如播放音乐、长期和服务器的连接,即使已不是屏幕当前的activity仍需要运行的情况,采用服务方式。服务将通过API触发启动或者通过IPC(Interprocess Communication)连接请求触发启动。服务将一直运行直至被关闭,或者内存不足时由系统关闭。一般而言,为了节省电量,服务应进行优化减少CPU的消耗和大量网络通信。服务可用于以下的场景:

1、用户离开activity后,仍需继续工作,例如从网络下载文件,播放音乐
2、无论activity出现(重现)或离开,都需持续工作,例如网络聊天应用 
3、连接网络服务,正在使用一个远程API提供的服务 
4、定时触发的服务,例如Linux中的cron。

Services主要有两种形式:

  (1)started形式:调用startedservice()启动,需要显式关闭,一般情况下一个service只负责一项操作,不向调用者返回结果。比如从网络上下载文件等。操作完成之后,service应该主动退出。

  (2)Bound形式:其他组件调用bindservice()和此service绑定。

Service基础:

  一般通过继承Service类来创建一个service,并且需要重写一些重要的方法,这些方法管理service生命周期或者用于其它组件绑定此服务,主要有以下方法:

  onstartCommand():当其它组件(比如一个Activity)调用startService()时,系统调用onstartCommand()。这个方法调用后,service在后台开启,要结束这个service,必须自己调用stopself()或者其它组件调用stopService()。

  onBind():当其他组件调用bindService()绑定这个服务时,系统调用onBind()。这个方法中必须包含一个返回IBinder,用于服务和客户端通信的接口。

  onCreate():当service第一次被创建时调用,在onstartCommand()和onBind()之前被调用。

  onDestory():service()关闭时调用,释放资源,结束相关线程。

在manifest文件中声明service:

  <service>元素作为<application>元素的子项

 

<manifest ... >  ...  <application ... >      <service android:name=".ExampleService" />      ...  </application></manifest>

 

创建Started类型的service

  其它组件调用startService()启动service,系统随之调用service的onstartCommand()。service一旦启动,必须自己调用stopSelf(),或者其它组件调用stopService()才能结束它。

  其它组件可以通过startservice()传递一个携带着数据的Intent给service,service端在onstartCommand()中接收传递过来的Intent。

一般情况下,可以通过继承以下两个类来创建service:

  Service:这种Service默认使用程序的主线程,使用时最好自己创建一个新线程来处理服务工作。

  IntentService:它是Service的子类,使用一个工作线程来处理请求,但是每次只能处理一个请求,不能同时处理多个请求。它需要实现onHandleIntent()方法来接收intent,处理客户端请求。

通过继承IntentService方式创建:

IntentService的工作流程如下:

  • 创建一个独立于主线程的的工作线程,执行传递给onstartCommand()的Intent。  
  • 创建一个工作队列,每次传递一个Intent给onHandleIntent()。
  • 所有请求被处理完后,Service会自动退出,不需要显式调用stopself()。
  • 默认提供的onBind()返回null。
  • onstartCommand()将Intent发送给一个工作队列,然后交给onHandleIntent()处理。

注意:需要实现onHandleIntent()方法和Service的构造器

继承IntentService的例子:

 

public class HelloIntentService extends IntentService {  /**   * 需要一个构造器, 必须调用父类构造器 IntentService(String)   * 并传入要创建的工作线程的名字   */  public HelloIntentService() {      super("HelloIntentService");  }  /**   *  IntentService在工作线程中调用这个方法   *  此方法返回后, IntentService关闭Service   */  @Override  protected void onHandleIntent(Intent intent) {      //一般情况下,我们在此做一些操作,比如下载一个文件。      //对于这个例子,我们只是让线程睡眠5s      long endTime = System.currentTimeMillis() + 5*1000;      while (System.currentTimeMillis() < endTime) {          synchronized (this) {              try {                  wait(endTime - System.currentTimeMillis());              } catch (Exception e) {              }          }      }  }}

 

  如果需要重写其它方法,比如:onCreate(),onstartCommand(),或者onDestroy(),一定要先调用父类实现,这样IntentService才能正确处理工作线程的生命周期。

  比如,onstartCommand()必须返回默认实现(它表示怎样将Intent传递给onHandleIntent())。

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();    return super.onStartCommand(intent,flags,startId);}

  除了onHandleIntent(),唯一一个不需要调用父类的方法是onBind(),但是Service在允许被绑定时才需要实现它。

***

 

Services学习(一)