Android Service 详解二:创建一个service

http://blog.csdn.net/nkmnkm/article/details/7317371


manifest中声明一个service

  跟activity以及其它组件一样,你必须在你的应用的manifest文件中声明所有的service们.

  要声明你的service,添加一个<service>元素作为<application>元素的儿子.例如:

[java]  view plain copy
  1. <manifest ... >  
  2.   ...  
  3.   <application ... >  
  4.       <service android:name=".ExampleService" />  
  5.       ...  
  6.   </application>  
  7. </manifest>  

  有多属性你可以包含在<service>元素中,比如启动service的权限和service运行所在的进程.android:name属性是哇一必须的它指定了service类的名字.一旦你发布了你的应用,你不应再改变这个名字,因为如果你改了,你可能使一些通过明确的intent来引用你的service的功能无法运行.

  就像一个activity,一个service可以定义intent过滤器来使得其它组件使用明确的intent调用自己.通过声明intent过滤器,你设备上的任意应用中的组件都可以通过给startService()传递匹配的intent来启动你的sevice

  如果你打算只在本应用内使用自己的service,那么你不需指定任何intent过滤器.不使用intent过滤器,你必须使用一个明确指定service的类名的intent来启动你的service

  另外,你也可以通过包含android:exported属性,并指定其值为”false”来保证你的service是私有的.即使你的service使用了intent过滤器,也会起作用.

创建一个"启动的"Service

  针对Android1.6或更早的版本:

  如果你创建的应用是针对Android1.6或更早版本的,你需要实现onStart()而不是onStartCommand()(Android2.0中,onStart()被废弃代替之以onStartCommand())

  更多关于如何兼容2.0之前版本的知识,请看onStartCommand()文档.


  一个启动的service,在被其它组件调用startService()来启动时,会导致serviceonStartCommand()方法被调用.

  当一个service被启动后,它的生命期就不再依赖于启动它的组件并且可以独立运行于后台,即使启动它的组件死翘翘了.所以,service应该工作完成后调用stopSelf()自己停止掉,或者其它组件也可以调用stopService()停止service


  一个应用组件,比如一个activity可以通过调用startService()启动service同时传递一个指定serviceservice所用的数据的Intentservice在方法onStartCommand()中接收这个Intent

  例如,假设一个activity需要保存一些数据到一个在线数据库中.这个activity可以通过传递一个intentstartService()来启动一个service并且把数据传给service来让servcie存储它们.serviceonStartCommand()接收intent,连接到Internet然后执行数据库事物.当事物完成后,service停止自己然后被销毁.


  小心:service默认运行在声明它的应用进程的主线程中.所以,如果你的service执行密集运算或阻塞操作并且与跟用户交互的activity位于相同的应用中,这个service将会拉低activity的性能.要避免影响应用的性能,你必须在service中启动一个线程.


  传统上,有两个类你可以从它派生来创建"启动的"service

  • Service

      这是所有service的基类.当你派生这个类时,在service中创建一个新的线程来做所有的工作是十分重要的.因为这个service会默认使用你的应用的主线程,这将拉低你的应用中所有运行的activity的性能

  • IntentService

      这是一个Service的子类,使用一个工作线程来处理所有的启动请求,一次处理一个.这是你不需你的service同时处理多个请求时的最好选择.你所有要做的就是实现onHandleIntent(),这个方法接收每次启动请求发来的intent,于是你可以做后台的工作.

IntentService类派生

  因为大多数"启动的"service不需要同时处理多个请求,可能从IntentService实现你的service是最好的选择.


IntentService做了以下工作:

  • 创建一个默认的工作线程在主线程之外执行所有派发到onStartCommand()intent

  • 创建一个工作队列,某个时间只传递一个intent到你的onHandleIntent()实现中,于是你不必担心多线程的问题.

  • 当所有开始的请求都处理后,停止service,所以你永远不需调用stopSelf()

  • 提供onBind()的默认实现,返回null

  • 提供一个onStartCommand()的默认实现,把intent加入到工作队列之后会传给你的onHandleIntent()实现.

  以上实现使得你可以仅仅实现onHandleIntent()来做要做的工作即可.(当然,你还是要实现一个小小的构造函数)


下面是一个实现IntentService的例子:

[java]  view plain copy
  1. public class HelloIntentService extends IntentService {  
  2.   
  3.   /**  
  4.    * 一个构造函数是必须的,并且你必须调用父类的IntentService(String)以传入工作线程的名字. 
  5.    */  
  6.   public HelloIntentService() {  
  7.       super("HelloIntentService");  
  8.   }  
  9.   
  10.   /** 
  11.    * IntentService在默认的工作线程中调用这个方法<p>   *当这个方法返回后,IntentService停止服务,如果能停止的话. 
  12.    */  
  13.   @Override  
  14.   protected void onHandleIntent(Intent intent) {  
  15.       // Normally we would do some work here, like download a file.  
  16.       // For our sample, we just sleep for 5 seconds.  
  17.       long endTime = System.currentTimeMillis() + 5*1000;  
  18.       while (System.currentTimeMillis() < endTime) {  
  19.           synchronized (this) {  
  20.               try {  
  21.                   wait(endTime - System.currentTimeMillis());  
  22.               } catch (Exception e) {  
  23.               }  
  24.           }  
  25.       }  
  26.   }  
  27. }</p>  

  以上就是你所有需要做的:一个构造函数和一个onHandleIntent()的实现.

  如果你决定重写其它的方法,比如onCreate()onStartCommand()oronDestroy(),要保证调用父类的对应实现,这样IntentService才能正确地处理工作线程的生命期.

比如,onStartCommand()必须返回默认的实现(其中实现了intent被传送到onHandleIntent()的逻辑)

[java]  view plain copy
  1. @Override  
  2. public int onStartCommand(Intent intent, int flags, int startId) {  
  3.     Toast.makeText(this"service starting", Toast.LENGTH_SHORT).show();  
  4.     return super.onStartCommand(intent,flags,startId);  
  5. }  

  除onHandleIntent()外,唯一不需调用父类实现的方法是onBind()(但是你只需在你的service允许绑定时才实现它)

  在下一节,你将看到同样的service类,从类Service派生时是如何实现的.这需要写更多的代码,但是当你需要处理同时发生的请求时(非序列化)这就是合适的做法了.






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值