Android中的Service
2015年05月06日 16:53:17 Android ⁄ 共 3412字 暂无评论 ⁄ 被围观 3,392次

在看 Mars 的教学视频《Android开发视频教学》中,他提到 Service 是 Android 系统中一个勤勤恳恳的劳模,在应用程序中从不露面但一直默默为其服务。

Android中的Service

首先说说什么是 Service。Android 系统中的 Service 是一个非常重要的应用程序组件,没有图形化界面,通常用来处理一些耗时长的操作,比如上传下载等,也可以用来处理一些在浏览界面之外的事,如后台音乐播放等。

官方文档中给出的解释是:

A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.

启动 Service 的方式有两种,Started 和 Bound。

Android中Service的生命周期

Started 方式启动 Service 时,调用者和服务之间没有联系,即使调用者退出了,服务仍然进行。简单实现一个 ExampleService,集成 Android 系统的 Service 类即可,但需要重写下列方法。

Code   ViewPrint
  1. package com.sinaapp.langtuteng.android.test;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.IBinder;
  5. import android.util.Log;
  6. public class ExampleService extends Service {
  7.     public static final String TAG = "ExampleService";
  8.     @Override
  9.     public IBinder onBind(Intent arg0) {
  10.         return null;
  11.     }
  12.     @Override
  13.     public void onCreate() {
  14.         Log.i(TAG, "ExampleService--->onCreate");
  15.         super.onCreate();
  16.     }
  17.     @Override
  18.     public void onDestroy() {
  19.         Log.i(TAG, "ExampleService--->onDestroy");
  20.         super.onDestroy();
  21.     }
  22.     @Override
  23.     public int onStartCommand(Intent intent, int flags, int startId) {
  24.         Log.i(TAG, "ExampleService--->onStartCommand");
  25.         return START_NOT_STICKY;
  26.     }
  27. }

当第一次运行程序,并通过 startService() 启动服务时,ExampleService 类会依次调用 onCreate() --> onStartCommand(),点击返回退出程序,不会调用 onDestroy()。注意,这里在 onCreate() 之后不会调用 onStart() 方法,是因为该方法在 API 5 之后已废弃了。

当再次运行程序时,只执行 onStartCommand() 方法。因为退出程序,后台的服务并不停止,一直存在并运行着,就不需要再次 create,除非在退出程序时调用过 stopService(),ExampleService 类则会调用 onDestroy()。所以说要想停止服务,必须 stopService 才行。

Bound 方式启动 Service 时,调用者和服务绑在一起,调用者一旦退出服务也就终止了。实现一个 BinderService 继承 Service 即可,但需要重写下列方法。

Code   ViewPrint
  1. package com.sinaapp.langtuteng.android.test;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.Binder;
  5. import android.os.IBinder;
  6. import android.util.Log;
  7. public class BinderService extends Service {
  8.     private static final String TAG = "BinderService";
  9.     private MyBinder binder = new MyBinder();
  10.     public class MyBinder extends Binder {
  11.         public BinderService getService() {
  12.             return BinderService.this;
  13.         }
  14.     }
  15.     @Override
  16.     public IBinder onBind(Intent intent) {
  17.         Log.i(TAG, "BinderService--->onBind");
  18.         return binder;
  19.     }
  20.     @Override
  21.     public void onCreate() {
  22.         Log.i(TAG, "BinderService--->onCreate");
  23.         super.onCreate();
  24.     }
  25.     @Override
  26.     public void onDestroy() {
  27.         Log.i(TAG, "BinderService--->onDestroy");
  28.         super.onDestroy();
  29.     }
  30.     @Override
  31.     public boolean onUnbind(Intent intent) {
  32.         Log.i(TAG, "BinderService--->onUnbind");
  33.         return super.onUnbind(intent);
  34.     }
  35.     public void MyMethod() {
  36.         Log.i(TAG, "BinderService--->MyMethod");
  37.     }
  38. }

当第一次运行程序,并通过 bindService() 启动服务时,BinderService 类会依次调用 onCreate() -->onBind(),点击返回退出程序,则会调用 onUnbind() -->onDestory()。

当再次运行程序时,还是和第一次一样,需要重新 create 这个服务。也可以不按返回键退出程序,手动调用 unbindService() 来停止服务。

 但是,以上两种方式中,当处理一些耗时特别长的工作时,需要在实现的 Service 类新启线程处理耗时操作,但是代码量大,费事儿。可以有一种简便的方法,那就是继承 IntentService 类,实现 onHandleIntent() 方法即可,特别简便。

在 IntentService 类中,主要有以下处理:
  1. 创建一个与应用程序主线程分开 worker thread 用来处理所有通过传递过来的Intent请求。
  2. 创建一个 work queue,一次只传递一个 intent 到 onHandleIntent() 方法中,从而不用担心多线程带来的问题。
  3. 当处理完所有请求后自动停止服务,而不需要我们自己调用 stopSelf() 方法。
  4. 默认实现了 onBind() 方法,返回值为 null。
  5. 默认实现了 onStartCommand() 方法,这个方法将会把我们的 intent 放到 work queue 中,然后在 onHandleIntent() 中执行。

所有关于 Service 的测试方法都已打包,供免费下载,具体细节可以下载代码运行后测试即可。

代码下载:百度云共享下载 | 360云盘下载(提取码:c5b5)

给我留言

留言无头像?