Service不完全解析

本篇的内容并不是介绍service使用方法和生命周期的,而是对其中的一些要点进行记录和分析。

我们都知道,Service是一个在后台执行的应用组件,用于在后台进行长期操作,例如进行网络事务,播放背景音乐等等。它又两种启动方式,如果其他的应用组件希望与该service进程内通信(IPC),可以通过与该service绑定来实现。关于生命周期的问题就不啰嗦了,直接放官档的图:

无论何种方式启动service,任何应用组件都可以使用该service。如果希望只有你自己的app才能使用该service,那么需要在manifest文件中加入android:exported属性,并将其设置为false。Android官方建议我们尽量使用显式的方式来启动service,从而保证app的安全。

另外,我们需要注意的是,在默认情况下service并不会重新开启一个独立的线程运行,而是运行于宿主进程的主线程中。显然,如果我们需要进行耗时操作,例如上面提到的播放背景音乐,网络操作等等,该如何解决?

    • 我们可以在activity中创建新线程,并在activity中对线程进行创建启动和销毁;
    • 使用asyncTask来完成任务;
    • 在service中新开一个线程来完成这些任务,以防ANR错误。

IntentService

当我们不需要同时处理多个请求的情况下,我们最好的解决方案是使用IntentService完成任务,而我们只需重写onHandleIntent()来完成处理逻辑即可。在IntentService进行了以下工作:

    • 新启动了一个worker线程来执行那些提交给onStartComand方法的intent任务。
    • 创建了一个work队列来存放多个请求任务,每次只向onHandleIntent()方法来传递一个intent来处理。
    • 当所有请求任务都完成后,则自动停止该service。
    • 默认的onStartCommand()方法中,将收到的intent参数传递给onHandleIntent()来处理。

下面是一个IntentService的示例:

public class HelloIntentService extends IntentService {

  /**
   * A constructor is required, and must call the super IntentService(String)
   * constructor with a name for the worker thread.
   */
  public HelloIntentService() {
      super("HelloIntentService");
  }

  /**
   * The IntentService calls this method from the default worker thread with
   * the intent that started the service. When this method returns, IntentService
   * stops the service, as appropriate.
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}

这里只需实现一个简单的构造函数和intent处理方法就可以了。当然,我们也可以根据需要重写service生命周期中的其他方法,但是请记得调用父类方法。我们需要清楚的是,所有提交给该service的任务都以intent的形式存放于一个队列中,IntentService里唯一的worker线程每次取一个intent来处理,都处理完后自动关闭IntentService。

如果希望多线程并发处理任务,那么需要继承service来处理任务了。这里就不演示具体代码了,但是有一点需要提醒一下。在onStartCommand方法会返回一个int值,通常我们返回父类的方法,这里的int值描述了当系统干掉service后的操作,它的几个常量选项如下:

    • START_NOT_STICKY : 当onStartCommand方法返回后,系统杀死了service,除非又有intent请求传递进来,否则将不会重新启动service。该选项可以很安全地确保当应用程序重启那些未完成的工作,而并不需要运行service时,避免service的启动运行。
    • START_STICKY: 当onStartCommand方法返回后,系统杀死了service,那么将会重新启动service,并执行onStartCommand方法,但是重新传递进来的intent并不是上一个intent了,而是使用null来代替(除非有新的intent请求)。该选项适用于类似于媒体播放器这种service,不执行任何命令,只是一直在运行等待任务。
    • START_REDELIVER_INTENT: 当onStartCommand方法返回后,系统杀死了service,那么将会重新启动service,并执行onStartCommand方法,重新传递进来的intent与上一个相同,随后而来的intent请求将会依次执行。该选项适用于类似下载任务的service,一直处于活跃状态,一旦挂掉就需要立即恢复。

另外,service还常常与notification相结合使用,使service可以运行到前台,例如音乐播放任务等等,可以与用户交互,这些内容以后再介绍。

时间: 2024-11-01 12:24:48

Service不完全解析的相关文章

Service使用全解析

Service 使用全解析 什么是Service Service是Android 的四大组件之一,主要处理一些耗时的后台操作逻辑,或者轮询操作等需要长期在后台运行的任务.甚至在程序退出之后,可以让Service继续在后台运行. Service的启动方式有三种:三种方式对应着三种不同的生命周期. startService启动服务.(简单使用) bindService绑定服务的方式启动服务. 先启动服务之后绑定服务. Service 的简单使用 startService启动服务是最简单的一种方式.我

C++请求web service与xml解析

1. C++解析XML的开源库 在项目中XML的解析使用的是开源的第三方库,TinyXML:这个解析库的模型通过XML文件,然后再内存中生成DOM模型,从而让我们可以很方便的遍历这颗XML树. DOM模型即文档对象模型,是将整个文档分成多个元素(如:书.章.节.段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系.先看一下TinyXML中的主要类和XML文档之间的对应关系,下图是TinyXML中主要class的类图,反应各个类之间的静态关系. TiXmlBase是所有类的基类,TiX

Android学习笔记:Android Service组件深入解析

在android开发系统(http://www.maiziedu.com/course/android-px/)中,service与activity一样是android的四大组件之一,他们不仅长得像,而且行为也比较类似.可是Service不像Activity在前台运行,而是与之呼应进行后台运行的服务:如果把 Activity当成下载软件的用户交互界面,而Service就是那个默默在后台运行的下载线程,所以Service的应用场景就是那些我们不需要它常驻前台但需要它一直在后台工作的时候,例如下载.

Service要点全解析

1.Service概述 Service的主要作用是,让系统可以在后台干一些不与用户交互的操作,这些操作可能会比较耗时,比如去下载一些网络资源等:也可能是一项长期运行的工作,比如说监听电话来电.播放音乐等.初听起来,Service与线程Thread很像,但Service和Thread完全是两个不同的东西啊. (1)Service不是运行在一个独立的进程中,它和我们的应用程序在同一个进程中: (2)Service也不是一个线程,相反,Service是运行在主线程的,因此我们不能直接在Service中

web service json 数组解析

?? boolean workexpMark = true; // 美发师工作经历json数组解析 org.json.JSONObject jsonObject = new org.json.JSONObject( workExperience); String array = jsonObject.getString("workExperence"); org.json.JSONArray jsonArray = new org.json.JSONArray(array); int

Android Service的全面解析

Service基本用法 基本用法即同进程下Activity与Service双向通信,先描述整体实现过程然后直接上代码: 新建一个继承自Service的类MyService,然后在AndroidManifest.xml里注册这个Service Activity里面使用bindService方式启动MyService,也就是绑定了MyService(到这里实现了绑定,Activity与Service通信的话继续下面的步骤) 新建一个继承自Binder的类MyBinder 在MyService里实例化

Android开发之使用Web Service进行网络编程

使用Web Service进行网络编程 Android应用通常都是执行在手机平台上.手机系统的硬件资源是有限的,无论是存储能力还是计算能力都有限.在Android系统上开发.执行一些单用户.小型应用是可能的, 但对于须要进行大量的数据处理.复杂计算的应用.还是仅仅能部署在远程server上,Android应用将仅仅是充当这些应用的client. 为了让Android应用与远程server之间进行交互,能够借助子Java的RMI技术,但这要求远程server程序必须採用Java实现:也能够借助于C

Android init源代码分析(2)init.rc解析

本文描述init.rc脚本解析以及执行过程,读完本章后,读者应能 (1) 了解init.rc解析过程 (2) 定制init.rc init.rc介绍 init.rc是一个文本文件,可认为它是Android系统启动脚本.init.rc文件中定义了环境变量配置.系统进程启动,分区挂载,属性配置等诸多内容.init.rc具有特殊的语法.init源码目录下的readme.txt中详细的描述了init启动脚本的语法规则,是试图定制init.rc的开发者的必读资料. Android启动脚本包括一组文件,包括

Android的init过程:init.rc解析流程

这几天打算看下安卓的代码,看优秀的源代码也是一种学习过程,看源代码的过程就感觉到,安卓确实是深受linux内核的影响,不少数据结构的使用方法全然一致.花了一中午时间,研究了下init.rc解析过程,做个记录. init.rc 文件并非普通的配置文件.而是由一种被称为"Android初始化语言"(Android Init Language.这里简称为AIL)的脚本写成的文件.在了解init怎样解析init.rc文件之前,先了解AIL很必要.否则机械地分析 init.c及其相关文件的源码毫