应用场景:

1  用于将后台逻辑(Service中)和UI逻辑(Activity中)进行解耦,实现Service功能的复用,为其他程序提供功能。

2  后台功能,由于Activity在进入后台时(OnStop)不会占用CPU进行运算,而Service在后台会一直占用CPU,用Service可以达到多任务效果。

3  默认情况下,Service运行在主线程(UI线程)中,因此耗时的操作(下载)需要在Service新建线程处理或者使用异步(AsyncTask)的方式进行。

4  桌面widget的功能需要用Service实现。

5  能提高进程优先级,当Android系统由于内存资源不足时会考虑将进程回收,此时若需要保证进程不会被结束,将Service运行在前台模式(foreground),此时该进程的优先级与前台进程一样。

6  IntentService类,对于简单的后台任务可以用IntentService实现。

相关回调函数以及生命周期

7  onCreate与onDestroy,相当于构造函数和析构函数,整个生命周期都只执行一次。不论startService或者bindService调用多少次,进程中的同一个Service只会在第一次时执行onCreate;而onDestroy需要调用stopService(若有startService,多次startService只需要一次stopService)和unbindService(若有bindService,每个bindService都要有相应的unbindService)后才会执行。

8  onBind,调用bindService时,若Service还没有启动,则根据不同的flags参数,会有不同的行为。

1) 0,默认值,不启动Service,而当有其他情况使得Service启动时,会自动绑定该Serivce。

2) BIND_AUTO_CREATE,若此时Service还没有启动,则直接启动Service。

3) BIND_DEBUG_UNBIND,会将bindService的调用栈保留以备调试的时候使用。

4) BIND_IMPORTANT,表明该Service非常重要,并且会将进程优先级设为前台进程级别。

5) BIND_NOT_FOREGROUND,不允许Service所在进程成为前台进程。

6) BIND_WAIVE_PRIORITY,不影响Service所在进程的调度和内存优先级。

  • onBind的主要作用是与调用者通过返回值IBinder建立连接,以便进行交互。

9  onUnbind,调用unbindService时执行,其返回值影响onRebind回调的运行情况。只有当返回值为true,onRebind才能运行。

10  onRebind,当Service由于内存不足被系统回收后,内存再次足够时,Service重新启动后就会执行。受onUnbind返回值影响。

11  onStartCommand,每次调用startService都会执行该回调函数。如果有一次性的任务可以放在该函数中执行,这样每次调用startService都会执行该任务。

后台服务最佳实践

12  不要在Service中直接进行耗时操作,这样会阻塞主线程(UI),应该将其放到另外的线程中运行。

13  对于简单可重复的任务,优先推荐使用IntentService。IntentService类中有自己的线程处理任务。通过在传递的Intent中附带数据,使用Broadcast将Service中信息传回客户端[1]进行通信。

14  使用AlarmManager、Thread和Service实现轮询,能只用AlarmManager就尽量不要带Service[2]

15  保持Service一直运行的方案:

1) 提升优先级,设为foreground运行,

2) 注册系统广播(开机启动、屏幕解锁等),

3) 开启两个Service,相互绑定监听,若对方被强制结束就将其重启(微信、QQ等),

4) 将程序安装到/system/app中,使其成为系统程序,需要root权限。

Service客户端相关

安卓Service组件的客户端就是能进行startService/stopService和bindService/unbindService操作的组件,一般情况下Activity、Broadcast receiver和Service都可以成为Service组件的客户端。

Activity是最常用的Service客户。对于Activity可以在其onCreate()/onDestroy(), onStart()/onStop(), onPause()/onResume()中实现启动和绑定Service/停止和解绑定操作(如果需要Service在后台运行,那么就不需要停止操作),因为这三组Activity回调在其生命周期中都是一一对应的,也就对应了Service资源的分配和回收情况。其中onCreate()/onDestroy()对应了服务需要在整个app的生命周期中都持续进行的情况,比如IM软件需要在后台持续进行网络通信服务,如果在其他两组回调中实现,那么一旦app进入后台,网络连接就会断掉(一般IM软件不会在onDestroy中停止Service,而是保持Service运行以保证不会错过消息);onStart()/onStop()对应的是该Activity在前台时需要的服务,比如更新Activity的UI界面时,这种情况下一旦onStop就结束Service并进行资源回收(主要防止serviceConnectionLeak),当Activity重新可见时,就重新开启并绑定Service。并不推荐在onPause()/onResume()中进行Service绑定和解绑定,因为这两个回调的执行频率非常高,应该要保持这中间的代码尽量只做轻量级的工作。除了在Activity的生命周期回调中绑定和解绑定Service外,还可以由UI事件触发(比如Button的click事件),此时必须要注意是否已经绑定,以及后续解绑定(可以放在onDestroy或onStop中),防止serviceConnectionLeak。

对于Broadcast receiver,其生命周中最主要就是onReceive回调,因此Service常常在此回调中开启。由于receiver的生命周期非常短(不能超过10s,否则就会ANR),因此不能使用bindService,只能startService开启服务。比如安卓的开机自启动就是通过接收BOOT_COMPLETED这个广播实现的,首先继承BroadcastReceiver类并在onReceive中开启Service,最后在AndroidManifest.xml 文件中注册该receiver。

Service和Service相互服务一般就是为了监控对方的运行状态以防止被系统收回。另外Service还可以直接为UI组件进行服务,比如在Service生命周期更新Notification的状态等。

Service绑定交互

Service与客户端绑定后进行交互主要有三种方法:Binder、Messenger和AIDL。

第一种方法适合与Service和客户运行在同一个进程中,比如Service由Activity启动并绑定的。在Service的onBind中返回Binder,客户Activity接收此Binder,并通过调用Binder公有方法甚至Service的方法与Service的交互。除非需要与其他进程的组件进行交互,就应该首选该方案。

第二种方法是使用Messenger,在此方法中Service需要定义一个Handler以处理各种Message。客户端通过该Service返回的Binder中获取到Messenger,通过向该Messenger发送Message,Service中的Handler进行处理,客户端也可以定义自己的Messenger,这样Service可以将Message传回给客户端。通过这种方式可以实现进程间的通信,这也是安卓推荐的IPC方式。

最后一种是使用AIDL(Android Interface Definition Language)。Messenger的底层实际上就是使用AIDL实现的。这种方法需要用aidl文件定义编程接口,然后由Android SDK 工具生成对应的接口类,最后实现这些接口。该方法与Messenger的优势是效率高,Messenger通过Handler进行消息处理,Handler使用消息队列,一次只能处理一个Message,AIDL则没有这种限制。缺点是服务器和客户端都需要aidl文件,它们之间的接口要保持兼容,因此IPC优先推荐使用Messenger。

除了通过Bind到Service进行交互外,还可以使用Application组件在一个程序的各个组件之间进行数据分享。主要思路是将数据保存在Application中,Application实现为一个Observer,其他组件实现为Listener,注册到Application上,这样当数据发生变动时,通知所有的Listener调用相应的回调。

Android Service 文档的更多相关文章

  1. Android SDK文档如何查找

    肯定很多人都会有疑问,怎样使用Android SDK 文档该如何使用呢?里面有那么多内容,又全是英文的,接下来告诉大家. 以下内容来自网络. ----------------------------- ...

  2. 三种方法解决android帮助文档打开慢

    三种方法解决android帮助文档打开慢   经查是因为本地文档中的网页有如下两段js代码会联网加载信息,将其注释掉后就好了 <link rel="stylesheet" h ...

  3. 提高打开Android本地文档的速度

    非常多Android开发人员在參考Android官方API时,都有一个令人头疼的问题:打开一个index.html平均都须要几分钟甚至更长.尤其是在打开API 8以上的版本号的时候.难道是网速不够好? ...

  4. Android 开发者文档 -- 应用基础知识

    https://developer.android.com/guide/components/fundamentals 应用基础知识 Android 应用采用 Java 编程语言编写.Android ...

  5. 关于android帮助文档打开慢

    打开慢的原因是:Doc目录下的html文件里含有访问google的js文件<link rel="stylesheet"href="http://fonts.goog ...

  6. Android API 文档 离线秒开方法

    http://blog.csdn.net/haifengzhilian/article/details/39898627 也是最近才看Android开发,但是,它的API文档无论是在线还是离线的,实在 ...

  7. Android XML文档解析(一)——SAX解析

    ---------------------------------------------------------------------------------------------------- ...

  8. 安装的Android SDK下无doc文件夹问题 以及关联Android帮助文档和查看文档 以及查看在线文档

    参考连接:https://blog.csdn.net/fangzicheng/article/details/78344521 https://jingyan.baidu.com/article/29 ...

  9. 受不了Android SDK文档打开缓慢问题,自己开发简易脱机浏览器。

    google android sdk离线文档打开的时候特别慢,据说是要从谷歌官网拉取一些东西导致的.脱机浏览能够解决该问题.PC端能够使用firefox. 可是Android端貌似没有支持脱机工作的浏 ...

随机推荐

  1. Python SocketServer源码分析

    1      XXXServer 1.1      BaseSever 提供基础的循环等待请求的处理框架.使用serve_forever启动服务,使用shutdown停止.同时提供了一些可自行扩展的方 ...

  2. Android Performance Optimization

    1.zipalign 2.ui优化 3.package size 4.RenderScript 5.Resource Shrinking & Code Shrinking 6.java cod ...

  3. sql基本增删改查语法

    sql语法学习(适合新手) 1.插入数据 语法格式: INSERT [INTO] <表名> [列名] VALUES <值列表> insert into students(sna ...

  4. Android 学习第9课,java android 项目的安装与启动过程

    android 安装过程: 开发工具先把.java文件转换成.class,然后转换成dx,再签名打包成apk,最后在设备上执行 adb install c:\xxx.apk android 启动过程: ...

  5. 怎样禁用或启用"最近使用的项目"

    1.右击“任务栏”——属性——‘开始’菜单——自定义——高级——去掉“列出我最近打开的文档”的勾选——确定.2.通过“组策略”来修改开始——运行——gpedit.msc——用户配置——管理模板——任务 ...

  6. 客户端HTTP断点续传的原理

    其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已. 打个比方,浏览器请求服务器上的一个文时,所发出的请求如下:假设服务器域名为wwww.scu.edu.cn,文件名为down. ...

  7. C++中的复制构造函数

    与C++中的构造函数相同,复制构造函数在对象生成过程中同样进行插入对应的Vtable虚表,但在成员变量赋值时,除具有复制构造函数的成员对象外,编译器合成复制构造函数其余均采用”Bitwise copy ...

  8. jQuery plugin: Autocomplete 参数及实例

    官网:jQuery plugin: Autocomplete          (注:此插件已经不再更新.它的继任者是jQuery UI的一部分,) 此插件依赖于 jquery 1.2.6 --- j ...

  9. mysql workbench is well-designed

    我用过mysql纯cli(command line),即纯命令行的执行环境,也用过navicat for mysql pro 破解版,甚至还用过比较高端的sqlyog,最后我还是选择了官方的workb ...

  10. [hdu 3376]Matrix Again

    这题就是真正的费用流了,用 大屁 就算不超时,你也有个 CE :数组 so large 拆点,费用取反,最大费用最大流即可了喵~ 不过似乎这题很不兼容 dijkstra 的样子 就算用 spfa 重赋 ...