http://blog.csdn.net/ryantang03/article/details/7770939

2012-07-21 18:21 75953人阅读 评论(15) 收藏 举报
分类:
Android(56)

Service是Android中四大组件之一,在Android开发中起到非常重要的作用,先来看一下官方对Service的定义:

Service翻译过来就是:Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。

Service有两种状态,“启动的”和“绑定”

A service is "started" when an application component (such as an activity) starts it by calling startService(). Once started, a service can run in the background indefinitely, even if the component that started it is destroyed. Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself.

A service is "bound" when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.

通过startService()启动的服务处于“启动的”状态,一旦启动,service就在后台运行,即使启动它的应用组件已经被销毁了。通常started状态的service执行单任务并且不返回任何结果给启动者。比如当下载或上传一个文件,当这项操作完成时,service应该停止它本身。

还有一种“绑定”状态的service,通过调用bindService()来启动,一个绑定的service提供一个允许组件与service交互的接口,可以发送请求、获取返回结果,还可以通过夸进程通信来交互(IPC)。绑定的service只有当应用组件绑定后才能运行,多个组件可以绑定一个service,当调用unbind()方法时,这个service就会被销毁了。

另外,在官方的说明文档中还有一个警告:

意思是service与activity一样都存在与当前进程的主线程中,所以,一些阻塞UI的操作,比如耗时操作不能放在service里进行,比如另外开启一个线程来处理诸如网络请求的耗时操作。如果在service里进行一些耗CPU和耗时操作,可能会引发ANR警告,这时应用会弹出是强制关闭还是等待的对话框。所以,对service的理解就是和activity平级的,只不过是看不见的,在后台运行的一个组件,这也是为什么和activity同被说为Android的基本组件。

Service生命周期中的一些方法:

通过这个图可以看到,两种启动service的方式以及他们的生命周期,bind service的不同之处在于当绑定的组件销毁后,对应的service也就被kill了。service的声明周期相比与activity的简单了许多,只要好好理解两种启动service方式的异同就行。

service生命周期也涉及一些回调方法,这些方法都不用调用父类方法,具体如下:

  1. <span style="font-family:Comic Sans MS;font-size:18px;">public class ExampleService extends Service {
  2. int mStartMode;       // indicates how to behave if the service is killed
  3. IBinder mBinder;      // interface for clients that bind
  4. boolean mAllowRebind; // indicates whether onRebind should be used
  5. @Override
  6. public void onCreate() {
  7. // The service is being created
  8. }
  9. @Override
  10. public int onStartCommand(Intent intent, int flags, int startId) {
  11. // The service is starting, due to a call to startService()
  12. return mStartMode;
  13. }
  14. @Override
  15. public IBinder onBind(Intent intent) {
  16. // A client is binding to the service with bindService()
  17. return mBinder;
  18. }
  19. @Override
  20. public boolean onUnbind(Intent intent) {
  21. // All clients have unbound with unbindService()
  22. return mAllowRebind;
  23. }
  24. @Override
  25. public void onRebind(Intent intent) {
  26. // A client is binding to the service with bindService(),
  27. // after onUnbind() has already been called
  28. }
  29. @Override
  30. public void onDestroy() {
  31. // The service is no longer used and is being destroyed
  32. }
  33. }</span>
  1. public class ExampleService extends Service {
  2. int mStartMode; // indicates how to behave if the service is killed
  3. IBinder mBinder; // interface for clients that bind
  4. boolean mAllowRebind; // indicates whether onRebind should be used
  5.  
  6. @Override
  7. public void onCreate() {
  8. // The service is being created
  9. }
  10. @Override
  11. public int onStartCommand(Intent intent, int flags, int startId) {
  12. // The service is starting, due to a call to startService()
  13. return mStartMode;
  14. }
  15. @Override
  16. public IBinder onBind(Intent intent) {
  17. // A client is binding to the service with bindService()
  18. return mBinder;
  19. }
  20. @Override
  21. public boolean onUnbind(Intent intent) {
  22. // All clients have unbound with unbindService()
  23. return mAllowRebind;
  24. }
  25. @Override
  26. public void onRebind(Intent intent) {
  27. // A client is binding to the service with bindService(),
  28. // after onUnbind() has already been called
  29. }
  30. @Override
  31. public void onDestroy() {
  32. // The service is no longer used and is being destroyed
  33. }
  34. }

关于Service生命周期还有一张比较易懂的图(来源于网络)

另外,这里要说明Service的一个子类,IntentService,首先看下官方文档的说明:

IntentServiceThis is a subclass of Service that uses a worker thread to handle all start requests, one at a time. This is the best option if you don't require that your service handle multiple requests simultaneously. All you need to do is implement onHandleIntent(), which receives the intent for each start request so you can do the background work.

IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。而在一般的继承Service里面如果要进行耗时操作就必须另开线程,但是使用IntentService就可以直接在里面进行耗时操作,因为默认实现了一个worker thread。对于异步的startService请求,IntentService会处理完成一个之后再处理第二个。

看下IntentService的具体实现:

  1. <span style="font-family:Comic Sans MS;font-size:18px;color:#222222;">public class HelloIntentService extends IntentService {
  2. /**
  3. * A constructor is required, and must call the super IntentService(String)
  4. * constructor with a name for the worker thread.
  5. */
  6. public HelloIntentService() {
  7. super("HelloIntentService");
  8. }
  9. /**
  10. * The IntentService calls this method from the default worker thread with
  11. * the intent that started the service. When this method returns, IntentService
  12. * stops the service, as appropriate.
  13. */
  14. @Override
  15. protected void onHandleIntent(Intent intent) {
  16. // Normally we would do some work here, like download a file.
  17. // For our sample, we just sleep for 5 seconds.
  18. long endTime = System.currentTimeMillis() + 5*1000;
  19. while (System.currentTimeMillis() < endTime) {
  20. synchronized (this) {
  21. try {
  22. wait(endTime - System.currentTimeMillis());
  23. } catch (Exception e) {
  24. }
  25. }
  26. }
  27. }
  28. }</span>
  1. public class HelloIntentService extends IntentService {
  2.  
  3. /**
  4. * A constructor is required, and must call the super IntentService(String)
  5. * constructor with a name for the worker thread.
  6. */
  7. public HelloIntentService() {
  8. super("HelloIntentService");
  9. }
  10.  
  11. /**
  12. * The IntentService calls this method from the default worker thread with
  13. * the intent that started the service. When this method returns, IntentService
  14. * stops the service, as appropriate.
  15. */
  16. @Override
  17. protected void onHandleIntent(Intent intent) {
  18. // Normally we would do some work here, like download a file.
  19. // For our sample, we just sleep for 5 seconds.
  20. long endTime = System.currentTimeMillis() + 5*1000;
  21. while (System.currentTimeMillis() < endTime) {
  22. synchronized (this) {
  23. try {
  24. wait(endTime - System.currentTimeMillis());
  25. } catch (Exception e) {
  26. }
  27. }
  28. }
  29. }
  30. }

关于停止Service,如果service是非绑定的,最终当任务完成时,为了节省系统资源,一定要停止service,可以通过stopSelf()来停止,也可以在其他组件中通过stopService()来停止,绑定的service可以通过onUnBind()来停止service。

关于Service还有很多知识,这里就不再一一列举,可以参考 http://developer.android.com/guide/components/services.html

加入我们的QQ群或微信公众账号请查看:Ryan's zone公众账号及QQ群

欢迎关注我的新浪微博和我交流:@唐韧_Ryan

Android中Service(服务)详解的更多相关文章

  1. Android中Service 使用详解(LocalService + RemoteService)

    Service 简介: Service分为本地服务(LocalService)和远程服务(RemoteService): 1.本地服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外L ...

  2. Android中Intent组件详解

    Intent是不同组件之间相互通讯的纽带,封装了不同组件之间通讯的条件.Intent本身是定义为一个类别(Class),一个Intent对象表达一个目的(Goal)或期望(Expectation),叙 ...

  3. WCF中队列服务详解

    WCF中队列服务详解 一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务 ...

  4. 【转载】Android Studio Service AIDL 详解

    公司产品之前IM这块存在很多问题,消息到达率低,加上协议上有些问题,丢消息频繁,所以需要重构IM,AIDL不能解决以上问题.好吧!那AIDL可以解决什么问题?什么是AIDL? 什么是AIDL? AID ...

  5. Android中mesure过程详解

    我们在编写layout的xml文件时会碰到layout_width和layout_height两个属性,对于这两个属性我们有三种选择:赋值成具体的数值,match_parent或者wrap_conte ...

  6. Android中的动画详解系列【4】——Activity之间切换动画

    前面介绍了Android中的逐帧动画和补间动画,并实现了简单的自定义动画,这一篇我们来看看如何将Android中的动画运用到实际开发中的一个场景--Activity之间跳转动画. 一.定义动画资源 如 ...

  7. [Android] Service服务详解以及如何使service服务不被杀死

    排版上的细节有些不好看,主要是我用的MarkDown编辑器预览和这里的不一样,在那个上面的样式很舒服.这里要改的地方太多就不想改了,将就看吧.下次写的时候注意.还有看到错误给我提啊. 本文链接:htt ...

  8. Kubernetes K8S之Service服务详解与示例

    K8S之Service概述与代理说明,并详解所有的service服务类型与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master Cent ...

  9. Android中shape属性详解

    一.简单使用 刚开始,就先不讲一堆标签的意义及用法,先简单看看shape标签怎么用. 1.新建shape文件 首先在res/drawable文件夹下,新建一个文件,命名为:shape_radius.x ...

随机推荐

  1. 并查集(图论) LA 3644 X-Plosives

    题目传送门 题意:训练指南P191 分析:本题特殊,n个物品,n种元素则会爆炸,可以转移到图论里的n个点,连一条边表示u,v元素放在一起,如果不出现环,一定是n点,n-1条边,所以如果两个元素在同一个 ...

  2. jquery toastr introduction

    1.资源 http://www.jq22.com/jquery-info476 http://www.jq22.com/yanshi476 Nuget Install-Package toastr 官 ...

  3. Docker(linux container) 所依赖的底层技术

    1 Namespace 用来做PID的隔离,有了namespace,在docker container里头看来,就是一个完整的linux的世界.在host看来,container里的进程,就是一个普通 ...

  4. javascript document.compatMode属性

    文档模式在开发中貌似很少用到,最常见的是就是在获取页面宽高的时候,比如文档宽高,可见区域宽高等. IE对盒模型的渲染在 Standards Mode和Quirks Mode是有很大差别的,在Stand ...

  5. CF# Educational Codeforces Round 3 B. The Best Gift

    B. The Best Gift time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  6. flexbox布局的兼容性

    http://ayqy.net/blog/flexbox布局的兼容性/ 写在前面 flex布局早在2009年就有了,而现在是2015年6月8日,使用最新的flex语法会发现支持程度并不好,即使是在“高 ...

  7. BZOJ2190 & 欧拉函数

    题意: 求1-n内互质数对个数 SOL: 裸欧拉函数,还有莫比乌斯反演的加速什么的,挖个坑. Code: /*============================================= ...

  8. 当编译AFNetworking 2.0时出现了Undefined symbols for architecture i386

    当将AFNetworking添加到工程后编译时出现 Undefined symbols for architecture i386: "_SecCertificateCopyData&quo ...

  9. [BZOJ2794][Poi2012]Cloakroom

    2794: [Poi2012]Cloakroom Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 167  Solved: 119[Submit][St ...

  10. Linux下bash: scp: command not found问题 或者装ssh包时报错 Requires: libedit.so.0()(64bit)

        一.用scp命令从物理主机向CentOS 6.1虚拟机传送文件,提示以下错误:bash: scp: command not found到CentOS 6.1虚拟机查看也缺少scp命令.该虚拟机 ...