android中文SDK--Service(一)

来源:互联网 发布:人工智能伏羲觉醒2电影 编辑:程序博客网 时间:2024/06/08 06:46
谢谢分享!转过去细细品读!
原文地址:android中文SDK--Service(一)作者:kangdong.yang

服务service

服务是一个应用程序的组件,运行在后台,执行一些耗时长的操作,他没有用户界面。另外的应用程序组件可以启动服务,服务一旦启动,即使用户切换到另一个应用程序,该服务也能继续在后台运行。另外,组件还可以绑定一个服务与其交互,还可以进行进程间通信(IPC)。

 

    服务有两种基本形式:

可启动的服务

    该服务通过组件如activity调用startService()方法启动。一般来说,一个可启动的服务执行一个单独的操作,并不返回结果。当操作结束,服务也就自动停止。

可绑定的服务

    该服务通过组件调用bindService()方法绑定。可绑定的服务提供一个客户端—服务端的接口,允许组件与其交互,发送请求,返回结果,还可以跨进程通信(IPC)。绑定的服务运行的时间与绑定它的组件一样长。多个组件可以同时绑定一个服务,当所有的组件都接触绑定后,服务停止并销毁。

 

    尽管该文档分开介绍两种类型的服务,但是服务可以同时具备这两种类型的特性,即可以启动,同时也可以绑定。服务对象的onStartCommand()方法允许组件启动服务,onBind()方法允许绑定服务。任何应用程序组件都可以使用服务,同样的,任何组件都可以使用activiry,通过传递一个Intent启动。但是,你也可以在manifest中那个服务声明为私有,阻断来自其他应用程序的访问。我们将在Declaring the service in the manifest中讨论。

注意:服务运行在持有它的进程的主线程中,除非你特别指定,否则服务并不创建属于自己的线程,也不运行在一个另外的进程中。也就是说,如果你的服务是用来执行一些消耗CPU或是阻塞操作的话,就应该在服务中新建一个线程去完成这些耗时的工作。使用一个分开的线程会减少发生ANR(应用程序无响应)错误的风险,而应用程序的主线程也就能专注于activity的用户界面处理。

 

 

基础

    要创建一个服务,必须继承Service父类,在你的实现中,必须重写一些回调方法,这些方法是处理service生命周期的一些关键事件,并为组件提供一种绑定service的机制。要重写的最重要的回调方法有:

 

onStartCommand()

    当另外的组件如activity通过startService()方法请求service启动时会调用service的onStartCommand()方法。一旦该方法被执行,service就启动并在后台运行了。如果你实现了该方法,那么你就应该在service完成它的工作后,通过调用stopSelf()或stopService()方法去停止该service。但是如果该service你只想提供绑定,就不必实现sonStartCommand()方法。

onBind()

    当另外的组件想要通过调用bindService()方法来绑定service,系统就会调用该方法。当重写实现这个方法的时候,你必须返回一个Ibinder对象,以提供一个客户端用来与该服务通信的接口。你必须实现该方法,如果你不想让该服务被绑定,那么可以返回null。

onCreate()

    当service第一次被创建时系统会调用该方法去执行一些初始化工作,在此之前,系统会调用onStartCommand()和onBind()方法。如果service已经在运行中,该方法则不会被调用。

onDestroy()

    当service不再被使用后被销毁时系统会调用该方法。你的service中应该是实现该方法,在方法中清理诸如线程,已经注册了的监听器,receivers等等的这些资源。这是service调用的最后一个方法。

 

    如果一个组件调用startService()(此时会调用onStartCommand())来启动一个service,那么该service就会一直保持运行,知道自己调用stopSelf()停止,或者另外的组件调用stopServcie()也可以停止该服务。

    如果一个组件调用bindService()来创建一个service(此时onStartCommand()不会被调用),那么只要当服务不再被任何的客户端绑定,系统就会销毁它。

    android系统只有在内存不足和必须为用户正在关注的acvitity回收系统资源时才会强制停止service。如果service绑定到一个用户关注的activity,那么它是不太可能被杀死的。如果service被声明在前台运行,那么它也几乎不可能被杀死。另外,service被启动并长时间运行后,随着时间的推移,系统会降低service在后台任务列表的位置,即优先级,service将会变得更容易被杀死。所以如果你的service是可启动的,那么你就必须设计系统重启它后的处理。如果系统杀死了你的service,当资源变得再次可用时将会重新启动它,尽管这也依赖于你从onStartCommand()返回的值,这将在后面讨论。了解更多关于系统会在何时销毁一个service的信息,参看Processes and Threading。

在manifest中声明service

    跟activity和其他组件一样,你必须在应用程序的manifest文件中声明所有的service。

    通过在<application>元素中添加一个字元素<service>来声明一个service,例如:

<manifest ... >
  ...
  <application ... >
      <service android:name=".ExampleService" />
      ...
  </application>
</manifest>

    在<service>元素中,还可以包含一些属性,如启动service的权限,service运行所在的进程等。

    就像activity一样,service也可以定义intent filters,这样其他的组件就可以用隐式intent调用该service。任何安装在你设备上的组件通过startService()方法传递一个intent,只要这个intent与你的服务所声明的intent filter匹配,那么就可以启动你的service。

    如果你不想让别的应用程序使用你的service,那么你就不需要也不应该提供任何intent filters。没有intent filter,你必须明确的指定类名来启动service。更多信息参看下面将讨论的启动一个服务Starting a service。

    另外,如果你想让service能让你的应用程序调用,只需要把android:exported属性设置成false即可。只要设置了该属性,那么即使为该service提供了intent filters也会被忽略掉。
原创粉丝点击