Chinaunix首页 | 论坛 | 博客
  • 博客访问: 811232
  • 博文数量: 210
  • 博客积分: 10002
  • 博客等级: 上将
  • 技术积分: 1840
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-18 09:56
文章分类

全部博文(210)

文章存档

2011年(1)

2010年(6)

2009年(65)

2008年(138)

我的朋友

分类: LINUX

2008-11-19 11:46:30

先说下对Service的理解,Service其实就是一个不可见的(invisible)运行在后台(background)的进程(process)。从优先级上来讲,它低于或等于任何对用户可见(visible)的进程,在有进程绑定(bound)到它时其优先级等同于任何对用户可见的进程。从存在的必要性来讲,一些应用需要单独的进程来处理CPU耗费大的事务,否则都放到一个进程会极其影响用户的交互体验,这点我想搞过图像处理的朋友都有这个体会吧:)

再来说下Service使用的两种方式。第一种是较为粗放的方式,通过调用[color=Blue]Context.startService()[/color]启动,调用[color=Blue]Context.stopService()[/color]结束,[color=Blue]startService()[/color]可以传递参数给Service。第二种方式是较为细腻的方式,通过调用[color=Blue]Context.bindService()[/color]启动,调用[color=Blue]Context.unbindservice()[/color]结束,还可以通过[color=Blue]ServiceConnection[/color]访问Service。二者可以混合使用,比如说我可以先startService再bindservice。
那么这两种方式是如何影响Service的生命周期(lifecycle)呢?还是先说下两种方式在各自单独使用的情况下对Service的生命周期的影响吧。startService后,即使调用startService的进程结束了Service仍然还存在,直到有进程调用stopService,当然Service如果想自杀([color=Blue]stopSelf()[/color])就没法了。而bindService后,Service就和调用bindService的进程同生共死了,也就是说当调用bindService的进程嗝屁了,那么它bind的Service也要跟着嗝屁,当然期间也可以调用[color=Blue]unbindservice[/color]让Service嗝屁。当两种方式混合使用时,比如说你startService了,我bindService了,那么只有你stopService了而且我也unbindservice了,这个Service才会嗝屁,相当于逻辑或为真就启动,逻辑与为假才结束。注意一点,Service不会被重复启动,就是说startService或者bindService触发系统生了个Service,后面再触发,系统是不会生二胎了。

下面还是以奥运倒计时为例,来说下我对Service用法的具体理解。
无论使用哪种方法,首先都要在manifest.xml文件中通过标记(tag)[color=Blue][/color]向系统注册我们的Service,否则启动不了,要是IDE能够自动帮我们注册就好了。
第一种方式很简单,在activity中通过下面这个方法调用启动Service:
[attach]167[/attach]
第一个参数是intent,而intent的参数里的第一个是谁发起intent,第二个是谁接收intent,startService的第二个参数是向Service传递参数,这里我们什么参数也不传递就填null。
结束Service也很简单,就不再多做解释了:
[attach]168[/attach]

在说第二种方法的时候我们先来看一下Service类里面需要我们重载的一个抽象方法(abstract method)[color=Blue]public abstract IBinder onBind(Intent intent)[/color]
这里其实是为了实现在绑定的时候获得对Service的使用,我的实现如下
[attach]169[/attach]
mBinder实例会在其它进程bindService的时候传递给该进程,这个后面再说,反正这里我们只需知道mBinder实例是要传递出去的就行了。再来看下mBinder是怎么回事,它是类LocalBinder的实例,而类LocalBinder继承自Binder,在LocalBinder里面我们实现一个获得自己Service引用的方法getService。

好了,有了这个铺垫,我们再看看在activity里我们是如何bind这个Service,如何获得mBinder的。在bind按键的事件响应里,有如下代码:
[attach]170[/attach]
bindService的第一个参数还是intent,这里就不重复讲了,第三个参数看名字也都明白,重点来看第二个参数mConnection,它的原型如下:
[attach]171[/attach]
这是一个interface类,用以监视Service的状态,获得其发出的信息。来看看第一个需要实现的方法onServiceConnected,如果我们bindService成功就会调用这个方法,前面我们在OlympicsService里实现的mBinder[color=Blue]在这里被从第二个参数传递进来[/color],通过在mBinder里实现的getService方法我们获得了该Service的引用!大伙该都该知道这个引用多有用吧,嘿嘿。既然是奥运倒计时嘛,我们就通过这个引用获得了当前的剩余时间。

取消bind非常简单,直接调用unbindService就行了,这里需谨记一点调用前必须确保已经binService了,否则会出现异常错误。另外当调用unbindService的时候,如果成功,系统会自动调用接口mConnection的onServiceDisconnected方法。
[attach]172[/attach]

结语:
这个例子只是在一个在应用程序里调用程序内Service的模式,称为本地服务(Local Service),Android还提供了调用程序外Service的模式,称为远程服务(Remote Service),后者偶还没耍,耍了再和大伙分享。最后来张通过bindService获得OlympicsService提供的奥运倒计时时间的效果。
阅读(831) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~