黑马程序员技术交流社区

标题: 【阳哥专栏】黑马Android教程-Android基础08Service [打印本页]

作者: 王震阳老师    时间: 2015-3-21 09:43
标题: 【阳哥专栏】黑马Android教程-Android基础08Service
本帖最后由 王震阳老师 于 2015-3-21 10:55 编辑

Android基础-08Service

黑马程序员上海校区招生火爆开启!阳哥约你在上海!



pdf原件,回复可见:


1. Service简介(★★★
很多情况下,一些与用户很少需要产生交互的应用程序,我们一般让它们在后台运行就行了,而且在它们运行期间我们仍然能运行其他的应用。为了处理这种后台进程,Android引入了Service的概念。
2. Android中的进程(★★2.1 Android中进程的种类
进程优先级由高到低,依次为:
1. Foreground process 前台进程        
2. Visible process 可视进程, 可以看见, 但不可以交互.        
3. Service process 服务进程        
4. Background process 后台进程        
  5. Empty process 空进程(当程序退出时, 进程没有被销毁, 而是变成了空进程)
2.2 进程的回收机制
Android系统有一套内存回收机制,会根据优先级进行回收。Android系统会尽可能的维持程序的进程, 但是终究还是需要回收一些旧的进程节省内存提供给新的或者重要的进程使用。
2.3 为什么用服务而不是线程
进程中运行着线程, Android应用程序刚启动都会开启一个进程给这个程序来使用。Android一个应用程序把所有的界面关闭时, 进程这时还没有被销毁, 现在处于的是空进程状态,Thread运行在空进程中, 很容易的被销毁了。
服务不容易被销毁, 如果非法状态下被销毁了, 系统会在内存够用时, 重新启动。
3. 案例-电话窃听器(★★★
需求:
开启一个服务监听用户电话,当电话被接通时开始录音,电话挂断时停止录音。
新建一个Android工程《电话窃听器》,包名:com.itheima.listenCall。
在src目录下新创建一个MyService类继承Service类,在该类中实现核心业务方法,实现监听电话,以及完成录音的功能。
在MainActivity类中启动Service
在AndroidManifest.xml文件中注册该Service。
:在Android中四大组件都需要在清单文件中进行注册。
在AndroidManifest.xml中添加权限。
:在该案例中,我们把录音文件存储在data/data/com.itheima.listenCall/files目录中,因此不需要声明外部存储的写权限。
将本工程部署到模拟器中,然后通过DDMS给该模拟器拨打电话,当我们接听一段时间并关闭后,发现控制台成功打印出了录音信息。
打开data/data/com.itheima.listenCall/files目录发现,录音文件被成功保存了。我们将该文件导出到电脑上,发现声音可以正常播放。
4. Service的生命周期(★★★★
service的生命周期,从它被创建开始,到它被销毁为止,可以有两条不同的路径。
A started service(标准开启模式)
被开启的service通过其他组件调用 startService()被创建。这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它。当service被停止时,系统会销毁它。
A bound service(绑定模式)
被绑定的service是当其他组件(一个客户)调用bindService()来创建的。客户可以通过一个IBinder接口和service进行通信。客户可以通过 unbindService()方法来关闭这种连接。一个service可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁service。
:Service这两中生命周期并不是完全分开的。
也就是说,你可以和一个已经调用了 [color=rgb(87, 137, 220) !important]startService()而被开启的service进行绑定。比如,一个后台音乐service可能因调用 [color=rgb(87, 137, 220) !important]startService()方法而被开启了,稍后,可能用户想要控制播放器或者得到一些当前歌曲的信息,可以通过[color=rgb(87, 137, 220) !important]bindService()将一个activityservice绑定。这种情况下,[color=rgb(87, 137, 220) !important]stopService() [color=rgb(87, 137, 220) !important]stopSelf()实际上并不能停止这个service,除非所有的客户都解除绑定。
Service的生命周期回调函数
activity一样,service也有一系列的生命周期回调函数,你可以实现它们来监测service状态的变化,并且在适当的时候执行适当的工作。
  下面的service展示了每一个生命周期的方法:


:不像是activity的生命周期回调函数,我们不需要调用基类的实现。
Service的生命周期图
这个图说明了service典型的回调方法,尽管这个图中将开启的service和绑定的service分开,但是你需要记住,任何service都潜在地允许绑定。所以,一个被开启的service仍然可能被绑定。实现这些方法,你可以看到两层嵌套的service的生命周期(拓展知识):
整体生命周期(The entire lifetime
  service整体的生命时间是从[color=rgb(87, 137, 220) !important]onCreate()被调用开始,到[color=rgb(87, 137, 220) !important]onDestroy()方法返回为止。
  和activity一样,service[color=rgb(87, 137, 220) !important]onCreate()中进行它的初始化工作,在[color=rgb(87, 137, 220) !important]onDestroy()中释放残留的资源。
  比如,一个音乐播放service可以在onCreate()中创建播放音乐的线程,在onDestory()中停止这个线程。
  [color=rgb(87, 137, 220) !important]onCreate() [color=rgb(87, 137, 220) !important]onDestroy()会被所有的service调用,不论service是通过[color=rgb(87, 137, 220) !important]startService()还是[color=rgb(87, 137, 220) !important]bindService()建立。
积极活动的生命时间(The active lifetime)
  service积极活动的生命时间(active lifetime)是从[color=rgb(87, 137, 220) !important]onStartCommand() [color=rgb(87, 137, 220) !important]onBind()被调用开始,它们各自处理由[color=rgb(87, 137, 220) !important]startService() [color=rgb(87, 137, 220) !important]bindService()方法传过来的[color=rgb(87, 137, 220) !important]Intent对象。
  如果service是被开启的,那么它的活动生命周期和整个生命周期一同结束。
  如果service是被绑定的,它们它的活动生命周期是在[color=rgb(87, 137, 220) !important]onUnbind()方法返回后结束。
  :尽管一个被开启的service是通过调用 [color=rgb(87, 137, 220) !important]stopSelf() [color=rgb(87, 137, 220) !important]stopService()来停止的,没有一个对应的回调函数与之对应,即没有onStop()回调方法。所以,当调用了停止的方法,除非这个service和客户组件绑定,否则系统将会直接销毁它,onDestory()方法会被调用,并且是这个时候唯一会被调用的回调方法。
管理生命周期
 当绑定service和所有客户端解除绑定之后,Android系统将会销毁它,(除非它同时被[color=rgb(87, 137, 220) !important]onStartCommand()方法开启)。
  因此,如果你的service是一个纯粹的绑定service,那么你不需要管理它的生命周期。然而,如果你选择实现[color=rgb(87, 137, 220) !important]onStartCommand()回调方法,那么你必须显式地停止service,因为service此时被看做是开启的。这种情况下,service会一直运行到它自己调用 [color=rgb(87, 137, 220) !important]stopSelf()或另一个组件调用[color=rgb(87, 137, 220) !important]stopService(),不论它是否和客户端绑定。
  另外,如果你的service被开启并且接受绑定,那么当系统调用你的 [color=rgb(87, 137, 220) !important]onUnbind()方法时,如果你想要在下次客户端绑定的时候接受一个[color=rgb(87, 137, 220) !important]onRebind()的调用(而不是调用 [color=rgb(87, 137, 220) !important]onBind()),你可以选择在 [color=rgb(87, 137, 220) !important]onUnbind()中返回true
  [color=rgb(87, 137, 220) !important]onRebind()的返回值为void,但是客户端仍然在它的 [color=rgb(87, 137, 220) !important]onServiceConnected()回调方法中得到 [color=rgb(87, 137, 220) !important]IBinder 对象。
  下图展示了这种service(被开启,还允许绑定)的生命周期:
5. Android中服务的调用(★★★5.1 案例-本地服务调用音乐播放器
新创建一个Android工程《音乐播放器》,包名:com.itheima.musicPlayer。
在res目录下新建一个文件夹raw(名字必须为raw,约定大于配置的原则),然后在raw目录中拷贝进一个音乐文件,注意文件名必须遵循Android资源文件的命名规则。
目录结构如下图:

在src目录下,新建一个MediaService继承Service类,在该类中实现核心服务的方法。
这是使用系统默认的布局文件,activity_main.xml清单如下:
使用默认的MainActivity类,在该类中完成业务的控制,代码清单如下:
在AndroidManifest.xml中注册Service。
将工程部署到模拟器上,点击播放,发现成功播放了音乐。点击暂停,发现音乐暂停了,然后点击播放,音乐再次响起。点击停止,问题来了,我们发现点击停止后再次点击播放音乐没能再次播放,因为这里面直接调用MediaPlayer的stop方法是有bug的。因此为了解决这样的问题,我们应该将停止调用层pause方法,同时只需调用MediaPlayer的seekTo(int)方法将音乐设置到开始位置。
控制台输出信息如下:
5.2 案例-远程服务调用商城支付
在Android平台中,各个组件运行在自己的进程中,他们之间是不能相互访问的,但是在程序之间是不可避免的要传递一些对象,在进程之间相互通信。为了实现进程之间的相互通信,Android采用了一种轻量级的实现方式RPC(Remote Procedure Call 远程进程调用)来完成进程之间的通信,并且Android通过接口定义语言(Android Interface Definition Language ,AIDL)来生成两个进程之间相互访问的代码,例如,你在Activity里的代码需要访问Service中的一个方法,那么就可以通过这种方式来实现了。
   AIDL是Android的一种接口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成 AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象。
   AIDL RPC机制是通过接口来实现的,类似Windows中的COM或者Corba,但他是轻量级的,客户端和被调用实现之间是通过代理模式实现的,代理类和被代理类实现同一个接口IBinder接口。
下面是案例-商城支付的步骤:
需求:分别创建两个工程,模拟一个支付平台,暂且叫支付宝,模拟一个商户端,叫商户。
商户可以调用支付宝发布的远程服务进行收款操作。
新创建一个Android工程《支付宝》,包名:com.itheima.alipay。在src目录下创建com.itheima.alipay.aidl包,然后在该包下创建AlipayRemoteService.aidl文件。在该文件中只声明一个接口,在接口里声明一个方法。文件清单如下:
:当该aidl文件创建好以后ADT会自动在gen目录下创建对应的类。
在《支付宝》src目录下创建com.itheima.alipay.service包,在该包中新建一个Service,叫AlipayService,该类实现付款功能。代码清单如下:
在《支付宝》工程的AndroidManifest.xml中注册该AlipayService。
创建一个新Android工程,名字叫《商户》,包名:com.itheima.shop。
使用默认的布局文件和默认的MainActivity类。
将《支付宝》工程中的AlipayRemoteService.aidl文件拷贝到《商户》工程的src目录下,同时注意添加对应的包名,要求包名必须跟该文件在原工程中的包名严格一致。《商户》src目录结构如下图:
编辑activity_main.xm布局文件
编写MainActivity类,在该类中实现核心方法

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


至此,本文档完!







作者: tubao1991    时间: 2015-3-21 10:33
虽然还不是很明白,先收藏,在学习!
作者: jackwang    时间: 2015-3-21 10:44
沙发!被我赶上了一次么?天啊!很激动!
作者: jackwang    时间: 2015-3-21 10:45
收藏收藏!顶!!!以后学android这些都要看的啊!
作者: 邓士林    时间: 2015-3-21 11:07
老师,你能不能讲解下如何将一个播放器做成一个service,而不是坐在activity中。
作者: 王震阳老师    时间: 2015-3-21 11:24
jackwang 发表于 2015-3-21 10:44
沙发!被我赶上了一次么?天啊!很激动!

哈哈,感谢支持。
作者: 王震阳老师    时间: 2015-3-21 11:25
邓士林 发表于 2015-3-21 11:07
老师,你能不能讲解下如何将一个播放器做成一个service,而不是坐在activity中。 ...

5. Android中服务的调用(★★★)5.1 案例-本地服务调用音乐播放器

本帖中第5章节就是讲的这个。
作者: 萍水相逢    时间: 2015-3-21 14:31
笔记挺不错的啊!谢谢分享
作者: 33姗姗    时间: 2015-3-21 15:02
阳哥,威武:victory:
作者: 邓士林    时间: 2015-3-21 17:04
王震阳老师 发表于 2015-3-21 11:25
5. Android中服务的调用(★★★)5.1 案例-本地服务调用音乐播放器

本帖中第5章节就是讲的这个。 ...

看了,明白了。手机客户端更新了三十几篇了,老师能不能把其他的文档发出来啊!手机看着不太舒服
作者: 王震阳老师    时间: 2015-3-21 17:24
邓士林 发表于 2015-3-21 17:04
看了,明白了。手机客户端更新了三十几篇了,老师能不能把其他的文档发出来啊!手机看着不太舒服 ...

我会尽快把pdf文档陆续更新出来。之后的每篇中都有pdf附件可供下载。
作者: 李增宽    时间: 2015-3-21 21:09
谢谢分享
作者: yekanghui    时间: 2015-3-21 21:29
我要进就业班,我要把安卓玩坏
作者: 王震阳老师    时间: 2015-3-21 21:47
yekanghui 发表于 2015-3-21 21:29
我要进就业班,我要把安卓玩坏

加油。
作者: 陈浩通    时间: 2015-3-21 21:52
现在看不懂,将来一定要看懂
作者: boycechan    时间: 2015-3-21 22:13
:lol非常不错,收藏了
作者: a1301155262    时间: 2015-3-21 22:17
写的不错,赞
作者: 落后就要挨打    时间: 2015-3-21 23:27
收藏一下,慢慢看
作者: 暗羽部落    时间: 2015-3-21 23:37
安卓学的怎么样  难吗
作者: 小亮smile    时间: 2015-3-21 23:41
加油!!!!!!!!顶顶顶
作者: Edison_Heung    时间: 2015-3-21 23:59
受益匪浅
作者: 青岛_黑马    时间: 2015-3-22 08:15
写的不错,赞
作者: 周位杰    时间: 2015-3-22 08:46
赞一个!。!
作者: wuliang    时间: 2015-3-22 10:17
杨哥专栏,必须顶。。。。。。。虽然现在还在打基础,看不懂
作者: 随心i    时间: 2015-3-22 12:10
阳哥出品必属精品,小手一抖收藏,嘿嘿……以后学习
作者: fantacyleo    时间: 2015-3-22 12:15
谢谢王老师,周末还在为黑马学员们发学习资料,辛苦了:handshake
作者: zqbemail    时间: 2015-3-22 12:30
笔记好全面。。
作者: 执笔画梦    时间: 2015-3-22 13:46
谢谢分享。
作者: ordinary    时间: 2015-3-22 13:46
收藏学习
作者: 王震阳老师    时间: 2015-3-22 15:01
fantacyleo 发表于 2015-3-22 12:15
谢谢王老师,周末还在为黑马学员们发学习资料,辛苦了

感谢支持。
作者: 王震阳老师    时间: 2015-3-22 15:02
随心i 发表于 2015-3-22 12:10
阳哥出品必属精品,小手一抖收藏,嘿嘿……以后学习

感谢支持。
作者: One_M    时间: 2015-3-22 16:34
收藏学习~!!!
作者: 大手牵小手    时间: 2015-3-22 21:26
很有用,表示感谢!
作者: ITheima-Ssmnr    时间: 2015-3-22 21:33
不错不错,赞一个
作者: 虚谷    时间: 2015-3-22 22:11
赞一个,非常不错
作者: 932773877    时间: 2015-3-23 00:08
我想看..........
作者: 932773877    时间: 2015-3-23 00:11
虽然我也还不是很明白,但是我还在前往的路上
作者: 33姗姗    时间: 2015-3-23 10:30
33姗姗 发表于 2015-3-21 15:02
阳哥,威武

烦人,我是颜色不一样烟火。。。
作者: yh903450130    时间: 2015-3-23 11:04
加油!!!!!!!!顶顶顶
作者: godot    时间: 2015-3-23 11:26
谢谢谢谢!
作者: ordinary    时间: 2015-3-23 16:17
没看一篇,用处都很大,先收藏
作者: 郝晓东    时间: 2015-3-23 18:12
谢谢喽~~~~~~~~~~
作者: 郝晓东    时间: 2015-3-23 18:19
感觉压力好大啊…自学又学不懂还没学到这…先收藏啦谢谢老师
作者: 王震阳老师    时间: 2015-3-23 21:31
ordinary 发表于 2015-3-23 16:17
没看一篇,用处都很大,先收藏

加油。
作者: 王震阳老师    时间: 2015-3-23 21:32
ordinary 发表于 2015-3-23 16:17
没看一篇,用处都很大,先收藏

下一篇将发布在最新的Android入门交流模块中。
作者: 王震阳老师    时间: 2015-3-23 21:32
郝晓东 发表于 2015-3-23 18:19
感觉压力好大啊…自学又学不懂还没学到这…先收藏啦谢谢老师

加油。
作者: SunshineCui    时间: 2015-3-23 22:16
赞一个,学习一下
作者: 王震阳老师    时间: 2015-3-23 22:34
ordinary 发表于 2015-3-23 16:17
没看一篇,用处都很大,先收藏

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:34
郝晓东 发表于 2015-3-23 18:12
谢谢喽~~~~~~~~~~

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:34
郝晓东 发表于 2015-3-23 18:19
感觉压力好大啊…自学又学不懂还没学到这…先收藏啦谢谢老师

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:34
Edison_Heung 发表于 2015-3-21 23:59
受益匪浅

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:34
周位杰 发表于 2015-3-22 08:46
赞一个!。!

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:34
wuliang 发表于 2015-3-22 10:17
杨哥专栏,必须顶。。。。。。。虽然现在还在打基础,看不懂

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:34
随心i 发表于 2015-3-22 12:10
阳哥出品必属精品,小手一抖收藏,嘿嘿……以后学习

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:35
zqbemail 发表于 2015-3-22 12:30
笔记好全面。。

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:35
执笔画梦 发表于 2015-3-22 13:46
谢谢分享。

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:35
932773877 发表于 2015-3-23 00:11
虽然我也还不是很明白,但是我还在前往的路上

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:35
33姗姗 发表于 2015-3-23 10:30
烦人,我是颜色不一样烟火。。。

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:35
yh903450130 发表于 2015-3-23 11:04
加油!!!!!!!!顶顶顶

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: 王震阳老师    时间: 2015-3-23 22:35
godot 发表于 2015-3-23 11:26
谢谢谢谢!

汇总贴:http://bbs.itheima.com/thread-180149-1-1.html
作者: macover    时间: 2015-3-23 22:54
收藏先,非常感谢
作者: mayor125    时间: 2015-3-24 09:44
顶顶顶。。
作者: 中华小便当    时间: 2015-3-24 16:41
回复看看
作者: 冻了冬天    时间: 2015-3-24 17:10
好多还有些不懂的,要是有视频就好了
作者: 感觉    时间: 2015-3-24 22:56
好极了,上海终于开班了
作者: se7en    时间: 2015-3-25 22:34
非常不错,谢谢分享。。。。。。。。。
作者: wwwlcy    时间: 2015-3-26 20:32
支持!!!
作者: yihuyixi2    时间: 2015-3-26 23:08
先收藏下,fighting!!!
作者: ellisontu    时间: 2015-3-27 21:03
谢谢分享,学习了!
作者: psttt    时间: 2015-3-28 01:11
争取明天都看下。mark
作者: 脚踏实地2015    时间: 2015-3-28 22:04
阳哥,威武
作者: Lois    时间: 2015-3-28 22:52
顶                                    
作者: 奔跑的孙莹    时间: 2015-3-29 00:48
阳哥 我要把你的资料都下载啦 你写的太好了!
作者: 小亮smile    时间: 2015-3-29 10:42
非常赞 非常赞  哈哈哈!!!
作者: 暗羽部落    时间: 2015-3-29 14:38
好厉害~~~
作者: JARVIS_YJ    时间: 2015-3-30 07:30
顶一个。。。。。。。。。
作者: zouxx    时间: 2015-3-30 17:12
:)好好学习一下
作者: 小小的黑马    时间: 2015-3-30 21:44
赞一个!!!!!!!!!!!!!!
作者: li子文    时间: 2015-4-1 18:14
谢谢楼主,的分享,
作者: 剑雨飘扬    时间: 2015-4-9 18:23
感谢阳哥
作者: z47057554    时间: 2015-4-13 00:17
谢谢分享:):)
作者: Doug    时间: 2015-4-13 19:04
回帖领pdf
作者: lbl624    时间: 2015-4-13 22:11
谢谢分享啊,非常有用
作者: 鲁柯    时间: 2015-4-15 20:40
第八份了  继续下
作者: sinbad88    时间: 2015-4-15 21:28
很好的学习资料,谢谢
作者: Hosing    时间: 2015-4-15 23:19
Thanks for Yang Brother's Note!
作者: 福禄娃    时间: 2015-4-18 10:01
多谢阳哥分享的笔记。很有用:loveliness:
作者: 彭春晓    时间: 2015-4-19 15:10
ndroid教程-Android基础05网络编程&消息处... [修改]
作者: 时间都去哪了    时间: 2015-4-23 07:46
啦啦啦德玛西亚
作者: 枪杆不如笔杆    时间: 2015-4-24 10:28
喜闻乐见!
作者: Catface    时间: 2015-4-28 10:23
前来学习一下
作者: caoyang521    时间: 2015-5-2 14:30
谢谢老师, 很不错的笔记,学习之
作者: godmmm    时间: 2015-5-9 14:36
好东西,感觉自己学的好烂
作者: 武召胜    时间: 2015-5-24 00:30
阳哥v587
作者: xiaoxu    时间: 2015-5-24 22:21
资料整理得很详细,看着让人赏心悦目
作者: yjsf216    时间: 2015-5-25 20:57
08了 加油
作者: 739262720    时间: 2015-5-27 00:26
感谢阳哥,我是合肥的:lol,冉俊勇同学
作者: 黑马飞    时间: 2015-5-27 06:46
总结的真好
作者: 王震阳老师    时间: 2015-5-27 09:32
739262720 发表于 2015-5-27 00:26
感谢阳哥,我是合肥的,冉俊勇同学

你已经在上课了吧
作者: DxxD    时间: 2015-5-27 13:42
看一看。。。。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2