• 博客园
  • 首页
  • 新随笔
  • 联系
  • 订阅
  • 管理
日 一 二 三 四 五 六
< 2011年6月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2
3 4 5 6 7 8 9
统计
  • 随笔 - 70
  • 文章 - 0
  • 评论 - 42
  • 引用 - 0
公告
  • 昵称: Tekkaman
    园龄: 4个月
    粉丝: 14
    关注: 2 +加关注

搜索

常用链接

  • 我的随笔
  • 我的空间
  • 我的短信
  • 我的评论
  • 更多链接

随笔分类

  • Agile Development(1) (rss)
  • Android(18) (rss)
  • ATL(12) (rss)
  • C++(7) (rss)
  • iOS(1) (rss)
  • Java(17) (rss)
  • Linux(1) (rss)
  • WTL(7) (rss)
  • 编程杂谈(4) (rss)
  • 人生感悟(1) (rss)
  • 数据结构(1) (rss)
  • 网络文摘(1) (rss)

随笔档案

  • 2011年9月 (2)
  • 2011年7月 (1)
  • 2011年6月 (23)
  • 2011年5月 (35)
  • 2011年4月 (9)

相册

  • 计算技术

最新评论

  • 1.Re:盘点富人和穷人九大经典差异
  • 很好
  • --袁腾波
  • 2.Re:Java之用句柄操作对象
  • 一直都不明白Java中句柄是怎么一回事,看了你的“遥控板”和“电视机”后终于明白了~
  • --大全全
  • 3.Re:Android之App的六种UI元素
  • @ 谦虚的天下
    呵呵,是错了,您真仔细
  • --Tekkaman
  • 4.Re:Android之App的六种UI元素
  • 楼主对通知Notification的理解有误吧
    应该是通知栏,而不是标题栏的
  • --谦虚的天下
  • 5.Re:Android之Content Providers
  • @ yanwei
    鄙人翻译的- -,是鄙人的阅读笔记,故相当粗糙。建议阅读原文。
  • --Tekkaman

阅读排行榜

  • 1.ATL、MFC、WTL CString 的今生前世(1639)
  • 2.Android之Content Providers(1354)
  • 3.如何剖析一个类(1294)
  • 4.剖析ATL、WTL CString的实现(1230)
  • 5.Android之Activity(862)

评论排行榜

  • 1.ATL、MFC、WTL CString 的今生前世(10)
  • 2.如何剖析一个类(7)
  • 3.WTL中对话框数据交换(6)
  • 4.Android之Activity(4)
  • 5.Android之Content Providers(4)
Android之Services

Services

  一个Service是一个应用程序组件,它能完成长时间运行的操作在后台,并且不提供用户接口。另一个应用程序组件能开启一个service并 且它将继续运行在后台即使用户转换到另一个应用程序。额外的,一个组件可以被绑定到一个service来和它交互甚至完成进程间通信。例如,一个 service可能操作网络带伤、播放音乐、执行I/O或和一个content provider交互,所有这些都是在后台进行。

  一个service主要有两个用途:

  1、Started

    一个service被开启当一个应用程序组件(例如activity)用startService()开启它。一旦开启,一个 service能无期限的运行在后台,即使创建它的组件被销毁。通常,一个启动的service完成一个单的操作,并且不返回结果给调用者。例如,它可能 下载蔌上传一个文件通过网络。当操作完成,服务应该停止它自己。

  2、Bound

    一个service处于Bound状态,当一个应用程序组件绑定它通过bindService()。一个bound service提供一个客户端/服务器接口,以允许组件和service交互、发送请求、获取结果甚至做跨进程的进程间通信(IPC)。一个bound service运行只有当另一个应用程序组件绑定它。更多的是,组件能一旦绑定到service,但当它们所有都取消绑定,这个service就被摧毁。

  虽然这篇文档主要单独地讨论两种不同类型的service,你的service可以两个都工作--它可以启动(无期限的运行)并且同样允许绑 定。这只是你的组件是否实现了两个onStartComamnd()回调的问题,来允许组件启动它并且onBind()允许绑定。

  不管你的应用程序是否启动、bound、或两个都是,任何一个应用程序组件都可以使用service(甚至从一个单独的应用程序),通过这种方 式,任何组件能使用一个activity--通过一个Intent开启。可是,你能声明service私有,在manifest文件里,并且阻止访问从其 它应用程序。

  警告 :一个service支它的主进程的主线程--service不创建它自己的线程并且不运行在单独的进 程(除非你指定)。这意味着,如果你的service将要去做任何耗CPU的工作或阻塞操作(例如MP3播放或网络),你应该新建一个线程为这个 service来完成那个工作。通过使用一个单独的线程,你将减少应用程序不响应(ANR)风险并且应用程序的主线程能专注于你的activity的用户 交互。

The Basics

  为了创建一个service,你必须创建一个service的子类(或已经存在类的子类)。在你的实现中,你需要需要覆盖一些回调函数,那些操作service生命周期关键方面并且给组件提供一个机制来绑定到serivce,如果合适。最重要的回调你应该覆盖的是:

onStartCommand()
系 统调这个方法当另一个组件,例如一个activity,请求启动这个service通过startService()。一旦这个方法执行,这个 service将启动并且无期限的运行在后台。如果你实现这个,那么停止service就是你的责任了当它的工作完成,通过调用stopSelf()或 stopService()。(如果你只希望提供绑定,你不需要实现这个方法)
onBind()
系 统调用这个方法当另一个组件希望绑定service(例如RPC),通过bindService()。在你这个方法的实现中,你必须提供一个客户使用的来 和这个service通信的接口,通过一个IBinder。你必须一直实现 这个函数,但如果你不希望允许绑定,那么你返回null。
onCreate()
系统调用这个方法当service第一次被创建,实现一次安装的步骤(在它调onStartCommand()和onBind()之前)。如果service已经在运行,那么这个方法不会调用。

onDestroy()
系统调用这个方法service不再使用将被摧毁。你的service应该实现这个来清理所有资源例如线程、注册的监听者、接收器等。这是service接收到的最后一个调用。

  如果一个组件启动一个service通过startService()(导致调用onStartCommand()),然后这个service维持运行直到它停止它自己通过stopSelf()或另一个组件停止它通过stopService()。

  如果一个组件调用bindService()来创建service(onStartCommand()不被调用),那么这个service当组件绑定它的时候运行。一量service被取消绑定从客户,系统销毁它。

  Android系统将强制停止一个service只有当内存很低并且它必须恢复系统资源为拥有用户焦点的activity。如果service 绑定到一个拥有用户焦点的activity,那么它不太可能被杀,如果service被声明为运行在前台(稍后讨论),那么 它将几乎永远不会被杀。否则,如果service启动,并且一直运行,那么 系统会降低它的位置在后台任何列表里随着时间,并且service将变得高度被杀--如果你的service一年非常,那么你必须设计它温柔的被系统重 启。如果系统杀死你的service,它重启它一量资源变得可利用(虽然这个也依赖于你从onStartCommand返回的值)。

Declaring a service in the manifest

  像很多activities(以及其它组件),你必须声明所有的services在你的应用程序manifest文件里。

  为了声明你的服务,加入<service>元素作为<application>元素的子元素。例如:

  有其它的属性你可以在<service>元素中来定义属性,例如启动service的权限和service运行在哪一个进程。

  就像一个activity,一个服务可以定义intent filters来允许其它组件激活服务使用隐含的intent。通过声明intent filters,任何其它应用程序的组件启动你的service如果你的service声明一个intent filter,匹配其它应用程序传递给startService()的intent。

  如果你计划只本地使用你的service(其它应用程序看不见),那么你不需要(也不应该)提供任何intent filters。没有任何intent filters,你必须启动这个service使用一个intent,显式的命名service类。

  额外的,你可以保证你的service是私有的对你的应用程序只有你包含android:exported属性并且设置它为"false"。这点非常有效,即使你的service提供intent filters。

Creating a Started Service

  一个开启的service是由另一个组件调用startService()开启,导致调用service的onStartCommand()方法。
  当一个service忘却,它有一个第一期周期独立于启动它的组件并且永远久运行在后台,即使创建它的组件被摧毁。这样,service应当停止它自己当工作完成通过stopSelf()函数,或另一个组件能停止它通过stopService()函数。
   一个应用程序组件例如一个activity可以开启service通过startService()并且传递一个Intent指定了service并且 包含任何数据给这个service来使用。Service接收这个Intent在onStartCommand()方法。
  例如,假 设一个activity需要保存一些数据给一个在线的数据库。这个activity可以启动一个伙伴service并且传递给它将要被保存的数据,通过传 递一个intent给startService()。这个service接收intent在onStartCommand(),连接到网络,并且完成数据 库事务。当事务完成,这个service停止它自己并且被摧毁。
   警告 :一个service运行 在和应用程序的同一个进程的主线程,默认。所以,如果你的service完成高耗能或阻塞工作当用户和这个应用的activity交互的时候,这个 service会减慢activity的性能。为了避免影响应用程序性能,你应该开始一个新线程在这个service中。
  
  通常的,有两种类型你能继承来创建一个新service:
Service
这是所有service的基类型。当你继承这个类,你新建一个线程来做service的工作就显得非常重要,因为这个service使用你应用程序的主线程,默认,这将降低你应用程序正在运行的所有activity的性能。
IntentService
这是一个Service人基类型,使用一个工作线程来操作所有开始的请求,一次一个。这是最佳选择如果你不需要你的service同时处理多个请求。所有你需要做的是实现 onHandleIntent(),接收intent从每个 开启的请求以便让你做后台工作。

Extending the IntentService class
  因为大多忘却的services不需要同时操作多个请求(会有多线程场景问题),可能的最好的方法是如果你实现你的service使用IntentService类。

  IntentService完成以下事情:
  1、建立一个默认的工作线程执行所有的intent从onStartCommand()发来的,线程独立于你应用程序的主线程。
  2、建立一个工作队列,一次传递一个intent给你的onHandleIntent()实现,这样你永远不用担心多线程。
  3、停止service在所有的请求都处理完后,所以你永远不用调用stopSelf()。
  4、提供默认的onBind()实现,即返回null的实现。
  5、提供默认的onStartCommand()实现,发送intent给工作队列,然后发给你的onHandleIntent()实现。

  所有这些加一起就是你所需要做的就是实现onHandleIntent()来完成你的工作。(虽然,你也需要提供一些构造函数为service)
  下面是一个实现IntenService的例子:
  


  这就是你所需要的:一个构造函数和一个onHandleIntent()的实现。

  如果你也决定覆盖其它方法,例如onCreate()、onStartCommand()、或onDestroy(),保证调用父类实现,以便IntentService能合适的操作工作线程的生命期。
  例如,onStartCommand()必须返回默认的实现(这决定intent怎样被送到onHandleIntent())
  除了onHandleIntent()之外,惟一的方法你不需要调用的是onBind()(你只需要实现如果你的service允许绑定)。

Extending the Service class
  就像你在前面看到的,使用IntentService让你的启动service变得非常简单。可是如果,你要求你的service实现多线程行为(不能使工作线程工作),那么你可以继承自Service类来操作这个intent。
  为了比较,下面的示例代码是一个Service的实现类,和上面的例子实现一样的功能使用IntentService。就是主产,对一个请求,它使用一个线程来袴工作并且一次只处理一个。
  <!-- 此处图略,可从SDK文档中查阅 -->
  你会发现,有更多的工作和使用IntentService相比。
  可是,因为你操作每一个调用onStartCommand()你自己,你可以同时处理多个请求。这不是这个例子做的事情,但是如果你需要的话,那么你可以建立一个线程为每一个请求并且立即运行它们(而不是等待前一个完成)。
   注意onStartCommand()必须返回一个整数。这个整数是一个值,描述系统怎么继续service当系统杀死它的时候(就像上面讨论 的,IntentService默认帮你实现,虽然你能改变它)。从onStartCommand返回的值必须是下面中的一个:

START_NOT_STICKY
如果系统杀死service在onStartCommand返回后,不要重新创建service,除非有等待的intent是发送。这是最安全的选项来避免运行你的service当不需要和当你的应用程序可以简单的重启任何未完成的工作。
START_STICKY
如 果系统杀死service在onStartCommand()返回后,重新创建service并且调用onStartCommand(),但不重发送 intent。相反,系统调用onStartCommand()用空intent,除非有等待的intent来启动service,在这种情况下,这些 intents被传送。这适合中级选手(或相似服务)不在执行命令,但运行无期限和等待一个工作。
START_REDELIVER_INTENT
如 果系统杀死service在onStartCommand()之后,重新创建service并且调用 用onStartComand()用最后一个intent,任何等待的intent都将被依次传递。这对一些service合适,它们常常活跃于处理一个 工作应该被立即恢复,就像下载一个文件。

Starting a Service
   你可以开始一个service从一个activity或其它应用程序组件通过传递一个Intent给startService()。Android系统 调用这个service的onStartCommand()方法并且传递它Intent。(你应该从不调用onStartCommand()直接)。
  例如,一个activity能启动示例service在前一节的(helloservice)使用一个显式 的intent用startService();

  startService()方法立即返回并且Android系统调用service的onStartCommand()方法。如果service没有运行,系统调用onCreate(),然后调用onStartCommand()。
   如果service也没有提供绑定,用startService()发送的intent是惟一的通信方法在组件和服务。可是,如果你希望service 发送一个结果回去,那么客户开始这个service能创建一个PendingIntent为一个广播并且传递它给service。然后Service能利 用广播来传送结果。

Stopping a service
   一个启动的service必须管理它自己的生命周期。也就是,这个系统不stop或摧毁除非系统要恢复内存,并且service一直运行在 onStartCommand()返回后。这样,service必须停止它自己通过stopSelf或另一个组件可以停止它通过 stopService()。
  一旦请求停止用stopSelf或stopService(),系统摧毁这个service尽快。
   可是,如果你的service在onStartCommand操作多个请求同时,那么 你不应该停止service当你已经完成一个请求,因为你可以已经接收到一个新的请求(在第一个请求后停止可能会终止第二个)。为了避免这个问题,你可以 使用stopSelf(int)来确保你的请求停止总是基于最近的请求。也就是,当你调用用stopSelf(int),你传递ID关于当前请求(ID传 递给onStartCommand)。那么如果service收到一个新的request在你能够调用stopSelf(int)之前,那么这个ID将不 会匹配并且service将不会停止 。
   警告 :你的应用程序停止它的服务当它完成工作这点非常 重要,为了避免浪费系统资源并且消耗电池。如果需要,其它组件可以停止service通过stopService()。即使你能绑定这个service, 你必须一直停止这个service你自己如果它收到一个onStartCommand()。

更多相关文章

  1. android 设计模式之单例模式详解
  2. Android进阶之数据存储+Preferences
  3. Android(安卓)checkCallingPermission()方法返回值问题
  4. android开发-界面设计基本知识Ⅲ
  5. Android生命周期组件Lifecycle使用详解
  6. Android平台中Wifi的初始化
  7. android API之ActivityGroup
  8. Android线程封装基类Thread
  9. Android提权代码zergRush分析

随机推荐

  1. Android(安卓)Fragment的简单应用
  2. android 4中新增的日历处理相关API
  3. Android(安卓)Color
  4. 高煥堂的四本Android开发新書(簡體完整版
  5. Android之一个简单计算器源代码
  6. Android(安卓)1.5 1.6 2.0 2.1 2.2 2.3 3
  7. Android(安卓)简单欢迎页面设计
  8. Android打开通讯录并获取数据
  9. 自定义类似于listView中Item背景
  10. Android的内存优化相关记录