Android应用开发 的一个重要组件——Android Service 与Activity不同 Service在Android中运行在后台 Service没有界面并且生命周期也与Activity不同 使用Service可以实现一些后台操作 例如从远程服务器上加载一个网页 可以使用Service在Android中实现多任务

Android Service概述

知道 如果系统资源变得紧张 Android Activity可以被启动、停止、销毁甚至可能被重新创建 而Service被设计成拥有更长的生命周期 Service在Android中可以从Activity、广播接收器(Broadcast receiver)或者由其他Service中启动

必须注意到的是 使用Service不会自动创建新的线程 所以 如果要在Service中实现一个简单的逻辑并且那不需要长时间处理 不必在一个单独的线程中运行它 但是 如果需要去实现一个复杂的逻辑并且会耗费长时间的处理 在创建新线程时必须小心 要不然由于Service运行在主线程可能引起ANR问题(应用程序无响应)

在Android中Service主要使用的场景如下:

  • 实现多任务(multi-task)
  • 进程间通信(IPC)

第一种情况的典型例子是 应用需要从远程服务端下载数据 在这种情况下 可以使用与用户交互的Activity 并在用户使用应用时启动Service 在后台运行完成工作 还有一种场景 当Service完成了任务发送信息给用户

在第二种情况下 想要"分享"一些通常的功能 这样不同的应用可以重用他们 例如 可以假设有一个可以发送邮件的Service 想要在几个应用分享这个服务 这样就不必重写新相同的代码 在这种情况下 可以使用IPC这样Service 暴露一个可以被其他应用调用的 "远程"接口

Service基础

现在对Service有了更多的了解 来创建它 在Android中创建一个Service需要继承Service类

public class TestService extends Service {  @Override  public IBinder onBind(Intent arg0) {        return null;  }}

可以看到 只实现了一个叫做onBinde的方法 在上面的示例中 使用了本地服务 所以方法返回null 正如前面提到的 Service有它自己的生命周期 因此可以重写一些回调方法 这样就能处理其不同的状态了:

public class TestService extends Service {  @Override  public void onCreate() {        super.onCreate();  }  @Override  public void onDestroy() {        super.onDestroy();  }  @Override  public int onStartCommand(Intent intent, int flags, int startId) {        return super.onStartCommand(intent, flags, startId);  }  @Override  public IBinder onBind(Intent arg0) {        return null;  }}

第一个方法onCreate只有在Service被创建的时刻被调用 如果Service已经在运行中 这个方法将不会被调用 不能直接调用它 它是由系统负责调用的

OnStartCommand方法是最重要的方法 因为它在需要启动Service的时候被调用 在这个方法中 拥有在运行Service时传递进来的Intent 这样就可以与Service交换一些信息 在这个方法中 实现自己的逻辑:如果不是耗时的操作可以直接在这个方法中执行 否则可以创建一个线程 正如你看到的那样 这个方法需要返回一个整型值 这个整型代表系统应该怎么样处理这个Service:

  • START_STICKY:使用这个返回值 如果系统杀死的Service将会重新创建 但是 发送给Service的Intent不会再投递 这样Service是一直运行的
  • START_NOT_STICKY:如果系统杀死了Service 不会重新创建 除非客户端显式地调用了onStart命令
  • START_REDELIVER_INTENT:功能与START_STICKY类似 另外 在这种情况下Intent会重新传递给Service

OnDestory是在Service将被销毁时系统调用的方法

一旦有了自定义的Service类 就要在Manifest.xml中声明 这样就可以使用了

<service android:name=".TestService"     android:enabled="true"/>

启动和停止Service

正如知道的 一个Service会被启动、最后会被停止 这样就可以完成它的任务了 假设从一个Activity中启动它 可以使用Intent传递给Service一些信息 假设的Activity有两个按钮 一个来启动 一个来停止Service:

btnStart.setOnClickListener(new View.OnClickListener() {   @Override  public void onClick(View v) {    Intent i = new Intent(MainActivity.this, TestService.class);    i.putExtra("name", "SurvivingwithAndroid");        MainActivity.this.startService(i);      }}); btnStop.setOnClickListener(new View.OnClickListener() {   @Override  public void onClick(View v) {    Intent i = new Intent(MainActivity.this, TestService.class);    MainActivity.this.stopService(i);  }});

在上面示例代码的第5行 创建一个传递类名的Intent来处理的服务 而且设置一些像名字这样的参数 然后在第7行的地方 启动这个Service 同样的方式 在17行停止了这个Service

android-service-tutorial-1

在开始按钮上点击 得到下面的Log:

可以注意到onCreate方法被调用了 因为这是第一次启动这个Service 如果在开始按钮上再次点击 系统不会调用onCreate方法 当在停止按钮上点击时 系统销毁这个Service

IntentService

正如以前提到的 Service运行在主线程中 所以 在Service中实现逻辑时要非常小心 要考虑如果这个逻辑是一个阻塞操作 或者需要很长时间才能结束 可能会引发ANR问题 在这种情况下 要将逻辑移到独立的线程中 这就意味着 要在onStartCommand方法中创建一个线程 然后运行它

从Service派生的另一个IntentService类可以简化的开发 当不需要在同一时间去处理多个请求时 这个类比较好用 这个类创建了一个工作线程来处理不同的请求 执行的操作如下:

  • 创建一个单独的线程来处理请求
  • 创建一个请求队列并偶尔传递一个Intent
  • 创建一个默认的onStartCommand实现
  • 在所有的请求执行完毕后结束Service

如果想要创建一个IntentService 需要继承IntentService类而不是Service类:

public class TestIntentService extends IntentService {   public TestIntentService() {    super("TestIntentService");      }   @Override  protected void onHandleIntent(Intent intent) {   } }

在这个实例中 只需要实现onHandleIntent方法 这里实现的外部逻辑不用关心操作是否耗时 因为这个方法在单独的线程中调用

自动启动Service

很多时候想要自动启动的服务 例如在开机时自动启动 知道需要一个组件来启动Service 那么 怎么样做到自动启动呢?可以使用一个广播接收器来启动服务 例如 如果想要在智能手机开机时候启动它 可以先创建一个广播接收器监听这个事件(开机) 然后启动Service

public class BootBroadcast extends BroadcastReceiver {  @Override  public void onReceive(Context ctx, Intent intent) {        ctx.startService(new Intent(ctx, TestService.class));  }}

在Manifest.xml中声明:

<receiver android:name=".BootBroadcast">    <intent-filter >    <action android:name="android.intent.action.BOOT_COMPLETED"/>          </intent-filter></receiver>

来源:http://www.importnew.com/9019.html