Service简单介绍及其使用

一、Service 简介

很多情况下,一些与用户很少需要产生交互的应用程序,我们一般让它们在后台运行就行了,而且在它们运行期间我们仍然能运行其他的应用。为了处理这种后台进程,Android 引入了 Service 的概念。

#    Service 在 Android 中是一种长生命周期的组件,它不实现任何用户界面,是一个没有界面的 Activity

  Service 长期在后台运行, 执行不关乎界面的一些操作比如: 网易新闻服务,每隔 1分钟去服务查看是否有最新新闻

#    Service 和 Thread 有点相似,但是使用 Thread 不安全, 不严谨

#    Service 和其他组件一样,都是运行在主线程中,因此不能用它来做耗时的操作

二、Android 中的进程

1)Android 中进程的种类

进程优先级由高到低,依次为:

    1.Foreground process 前台进程

    2. Visible process 可视进程, 可以看见, 但不可以交互.

    3. Service process 服务进程

    4. Background process 后台进程

    5. Empty process 空进程(当程序退出时, 进程没有被销毁, 而是变成了空进程)

2)进程的回收机制

        Android 系统有一套内存回收机制,会根据优先级进行回收。Android 系统会尽可能的维持程序的进程, 但是终究还是需要回收一些旧的进程节省内存提供给新的或者重要的进程使用。

#  进程的回收顺序是:从低到高

当系统内存不够用时, 会把空进程一个一个回收掉

# 当系统回收所有的完空进程不够用时, 继续向上回收后台进程, 依次类推

#  但是当回收服务, 可视, 前台这三种进程时, 系统非必要情况下不会轻易回收, 如果需要回收掉这三种进程, 那么在系统内存够用时, 会再给重新启动进程;但是服务进程如果用户手动的关闭服务, 这时服务不会再重启了。

3)为什么用服务而不是线程

      进程中运行着线程, Android 应用程序刚启动都会开启一个进程给这个程序来使用。Android 一个应用程序把所有的界面关闭时, 进程这时还没有被销毁, 现在处于的是空进程状态,Thread 运行在空进程中, 很容易的被销毁了。

       服务不容易被销毁, 如果非法状态下被销毁了, 系统会在内存够用时, 重新启动。

三、Service 的生命周期

service 的生命周期,从它被创建开始,到它被销毁为止,可以有两条不同的路径。

被开启的 service 通过其他组件调用 startService()被创建。这种 service 可以无限地运行下去,必须调用 stopSelf()方法或者其他组件调用 stopService()方法来停止它。当service 被停止时,系统会销毁它。A bound service (绑定模式)被绑定的 service 是当其他组件(一个客户)调用 bindService()来创建的。客户可以通过一个 IBinder 接口和 service 进行通信。客户可以通过 unbindService()方法来关闭这 种连接。一个 service 可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁service。

Tips Service 的这两中生命周期并不是完全分开的

也就是说,你可以和一个已经调用了 startService()而被开启的 service 进行绑定。比如,一个后台音乐 service 可能因调用 startService()方法而被开启了,稍后,可能用户想要控制播放器或者得到一些当前歌曲的信息, 可以通过 bindService()将一个 activity 和 service 绑定。 这种情况下, stopService()或 stopSelf()实际上并不能停止这个 service,除非所有的客户都解除绑定。

Service  的生命周期回调函数

和 activity 一样,service 也有一系列的生命周期回调函数,你可以实现它们来监测 service 状态的变化,并且在适当的时候执行适当的工作。

下面的 service 展示了每一个生命周期的方法:


Service生命周期图

这个图说明了 service 典型的回调方法, 尽管这个图中将开启的 service 和绑定的service 分开,但是你需要记住,任何 service 都潜在地允许绑定。所以,一个被开启的 service 仍然可能被绑定。实现这些方法,你可以看到两层嵌套的 service 的生命周期。

积极活动的生命时间

service 积极活动的生命时间(active lifetime)是从 onStartCommand() 或onBind()被调用开始,它们各自处理由 startService()或 bindService()方法传过来的 Intent 对象。

如果 service 是被开启的,那么它的活动生命周期和整个生命周期一同结束。

如果 service 是被绑定的,它们它的活动生命周期是在 onUnbind()方法返回后结束。

Tips :尽管一个被开启的 service 是通过调用 stopSelf() 或 stopService()来停止的,没有一个对应的回调函数与之对应,即没有 onStop()回调方法。所以,当调用了停止的方法,除非这个 service 和客户组件绑定,否则系统将会直接销毁它,onDestory()方法会被调用,并且是这个时候唯一会被调用的回调方法。

管理生命周期

当绑定 service 和所有客户端解除绑定之后,Android 系统将会销毁它, (除非它同时被 onStartCommand()方法开启)。因此,如果你的 service 是一个纯粹的绑定 service,那么你不需要管理它的生命周期。、

然而,如果你选择实现 onStartCommand()回调方法,那么你必须显式地停止service,因为 service 此时被看做是开启的。这种情况下,service 会一直运行到它自己调用 stopSelf()或另一个组件调用 stopService(),不论它是否和客户端绑定。

另外,如果你的 service 被开启并且接受绑定,那么当系统调用你的 onUnbind()方法时,如果想要在下次客户端绑定时候接受一个 onRebind()的调用(而不是调用 onBind()),你可以选择在 onUnbind()中返回 true。onRebind()的返回值为 void,但是客户端仍然在onServiceConnected()回调方法中得到 IBinder 对象。

四、远程服务调用实例

在 Android 平台中,各个组件运行在自己的进程中,他们之间是不能相互访问的,但是在程序之间是不可避免的要传递一些对象, 在进程之间相互通信。     为了实现进程之间的相互通信, Android采用了一种轻量级的实现方式RPC(Remote Procedure Call 远程进程调用)来完成进程之间的通信,并且 Android 通过接口定义语言(Android Interface DefinitionLanguage ,AIDL)来生成两个进程之间相互访问的代码,例如,你在 Activity 里的代码需要访问 Service 中的一个方法,那么就可以通过这种方式来实现了。

AIDL 是 Android 的一种接口描述语言; 编译器可以通过 aidl 文件生成一段代码, 通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个 Activity 中, 访问另一个Service 中的某个对象, 需要先将对象转化成 AIDL 可识别的参数(可能是多个参数), 然后使用 AIDL 来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象。

AIDL RPC 机制是通过接口来实现的,类似 Windows 中的 COM 或者 Corba,但他是轻量级的, 客户端和被调用实现之间是通过代理模式实现的, 代理类和被代理类实现同一个接口 IBinder 接口。

下面是案例-商城支付的步骤:

需求:分别创建两个工程,模拟一个支付平台,暂且叫支付宝,模拟一个商户端,叫商户。商户可以调用支付宝发布的远程服务进行收款操作。

1)新创建一个 Android 工程《支付宝》。在 src 目录下创建 com.share.alipay.aidl 包,然后在该包下创建 AlipayRemoteService.aidl 文件。在该文件中只声明一个接口,在接口里声明一个方法

package com.share.alipay.aidl;

interface AlipayRemoteService{                                                                                            

           boolean forwardPayMoney(float money);

}

Tips:当该 aidl 文件创建好以后 ADT 会自动在 gen 目录下创建对应的类。

2)在《支付宝》src 目录下创建 com.share.alipay.service 包,在该包中新建一个Service,叫 AlipayService,该类实现付款功能。代码清单如下:

3)在《支付宝》工程的 AndroidManifest.xml 中注册该 AlipayService。

4)创建一个新 Android 工程,名字叫《商户》,包名:com.share.shop。使用默认的布局文件和默认的 MainActivity 类。

将《支付宝》工程中的 AlipayRemoteService.aidl 文件拷贝到《商户》工程的 src 目录下,同时注意添加对应的包名,要求包名必须跟该文件在原工程中的包名严格一致。

5)编辑 activity_main.xm 布局文件。

6)编写 MainActivity 类,在该类中实现核心方法。


7)先将《支付宝》部署到模拟器,然后将《商户》部署到模拟器,然后在《商户》界面输入一个金额, 然后点击确定支付, 发现 《商户》 工程已经成功通过远程服务调用了 《支付宝》中的服务。


至此,本篇完!


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容