Service 服务

A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background
Service是一个长期运行在后台,并不提供界面的应用组件。其余组件能够启动一个服务,而且即便用户切换到其余的应用,该服务仍可在后台继续运行。另外,组件能够把某个服务邦定到本身,来与其交互通讯,甚至包括执行进程间通讯(IPC).例如,某个服务可能在处理来自后台的,网络传输,放音乐,执行文件I/O,或者与内容提供者交流.
A service can essentially take two forms:服务的两个重要的形态:
Started 启动态
A service is "started" when an application component (such as an activity) starts it by calling startService().Once started, a service can run in the background indefinitely, even if the component that started it is destroyed.Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself.
当某个应用组件调用startService()方法启动服务时,服务就处于启动态(started).一旦启动,即便启动服务的组件已销毁,该服务仍能无限的运行在后台.   通常,一个启动的服务只执行单一操做,且并不返回结果给它的调用者.好比,某服务可能下载或上传文件到网上,当操做完成,该服务应该本身中止本身.
Bound 邦定态
A service is "bound" when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.
当一个应用组件调用bindService()方法,邦定服务,该服务就处理邦定态。一个邦定的服务提供一个客户端服务接口,全部的组件经过这个接口与服务交流,发送请求,获取结果,而且甚至是进程间通讯。只有其余应用组件邦定到该服务,该邦定服务才运行。能够同时邦定多个组件到该服务,但只有当全部邦定的组件都松邦后,该服务才销毁。
Although this documentation generally discusses these two types of services separately, your service can work both ways—it can be started (to run indefinitely) and also allow binding. It's simply a matter of whether you implement a couple callback methods: onStartCommand() to allow components to start it and onBind() to allow binding.
虽然本文档概要的分别讨论服务的这两种类型,但你的服务是能够一块儿工做的—它能够在被运行(无限运行)的同时容许邦定。你只需简单的执行两个方法便可:容许组件启动它的onStartCommand()方法和容许邦定的onBind()方法.
Regardless of whether your application is started, bound, or both, any application component can use the service (even from a separate application), in the same way that any component can use an activity—by starting it with an Intent. However, you can declare the service as private, in the manifest file, and block access from other applications. This is discussed more in the section about Declaring the service in the manifest.
与您的应用被开启,邦定或者同时处理开启,邦定状态无关,应用的任何组件可以使用该服务(甚至是独立的其余应用),一样任何组件可以使用活动—用Intent意图启动。可是,你能够在manifest文件中,将服务声明为私有,并阻止来自其余应用的访问。关于此的详细讨论,在Declaring the service in the manifest一节中。
Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.
注意:服务运行在它的宿主进程的主线程中—服务不建立它本身的线程,而且不会运行在一个独立的进程里(除非你另有指定)。这里的意思是:若是你的服务要执行任何密集使用CPU的操做,或者阻塞操做(好比MP3回放或者网络),你应该给服务建立一个新的线程来处理那些事情。经过使用独立的线程,你将能减小应用无响应错误的风险(ANR),而且能让应用的主线程保持处理,用户与你的活动之间的交互操做.
The Basics基础
To create a service, you must create a subclass of Service (or one of its existing subclasses). In your implementation, you need to override some callback methods that handle key aspects of the service lifecycle and provide a mechanism for components to bind to the service, if appropriate. The most important callback methods you should override are:
要建立一个服务,你必须建立Service服务的一个子类(或者它的一个存在的子类).在您的实现中,须要复写处理服务生命周期的一些回调方法,而且在适当的条件下,提供组件邦定到服务的机制。你应该复写的最重要的回调方法是:
onStartCommand()
The system calls this method when another component, such as an activity, requests that the service be started, by calling startService(). Once this method executes, the service is started and can run in the background indefinitely. If you implement this, it is your responsibility to stop the service when its work is done, by calling stopSelf() or stopService(). (If you only want to provide binding, you don't need to implement this method.)
当其余的组件,好比某个活动,调用startService()方法请求启动服务时,系统调用这个方法.一旦这个方法执行,该服务就处于已启动状态,而且无限循环的运行在后台。若是你实现这个方法,当服务的工做处理完成后,你要负责中止这个服务.经过调用stopSelf()方法或stopService()方法。(如你只想提供邦定,你不须要实现这个方法)
onBind()
The system calls this method when another component wants to bind with the service (such as to perform RPC), by calling bindService(). In your implementation of this method, you must provide an interface that clients use to communicate with the service, by returning an IBinder. You must always implement this method, but if you don't want to allow binding, then you should return null.
当其余的组件,调用bindService()方法,想邦定到该服务时,系统调用该方法。在你的本方法实现中,你必须提供一个接口返回一个IBinder,来让用户经过此接口与服务通讯。你必须老是实现这个方法,可是你若不想容许邦定,那么你应该返回null.
onCreate()
The system calls this method when the service is first created, to perform one-time setup procedures (before it calls either onStartCommand() or onBind()). If the service is already running, this method is not called.
当服务第一次被建立时系统调用本方法,执行一次设置程序(调用onStartCommand()方法或onBind()方法以前).若是该服务已经在运行,这个方法不会被调用。
onDestroy()
The system calls this method when the service is no longer used and is being destroyed. Your service should implement this to clean up any resources such as threads, registered listeners, receivers, etc. This is the last call the service receives.
当该服务再也不使用,而且即将要销毁时,系统调用本方法。您的服务应该实现这个方法,来清除像线程,注册监听器,接收器等等的全部资源。这是该服务能收到的最后一个调用。
If a component starts the service by calling startService() (which results in a call to onStartCommand()), then the service remains running until it stops itself with stopSelf() or another component stops it by calling stopService().
若是一个组件调用startService()方法启动了该服务(会致使调用onStartCommand()方法),那么该服务将保持运行,直到它用stopSelf()方法中止了本身,或者另外一个组件调用了stopService()方法中止了它。
If a component calls bindService() to create the service (and onStartCommand() is not called), then the service runs only as long as the component is bound to it. Once the service is unbound from all clients, the system destroys it.
若是某个组件调用bindService()方法建立服务(而且onStartCommand()没被调用),那该服务只有当该组件邦定到它时才运行。一旦该服务从全部的客户端解除,系统将销毁它.
The Android system will force-stop a service only when memory is low and it must recover system resources for the activity that has user focus. If the service is bound to an activity that has user focus, then it's less likely to be killed, and if the service is declared to run in the foreground (discussed later), then it will almost never be killed. Otherwise, if the service was started and is long-running, then the system will lower its position in the list of background tasks over time and the service will become highly susceptible to killing—if your service is started, then you must design it to gracefully handle restarts by the system. If the system kills your service, it restarts it as soon as resources become available again (though this also depends on the value you return from onStartCommand(), as discussed later). For more information about when the system might destroy a service, see the Processes and Threading document.
只有当缺乏内存及必须为用户的焦点活动恢复系统资源时,Android系统将强制中止一个服务。若是服务被邦定到一个捅有用户焦点的活动,那么它不多会被杀掉,而且若是该服务被声明成run in the foreground (运行在前台,后面讨论),那么该服务几乎不被杀掉。不然,若是服务开启后,长期在运行,那么随着时间的延长,系统会下降它在后台任务列表中的位置,并将变得极有可能被杀掉-若是你的服务被开启了,那么你应把它(服务)设置成彻底能够由系统重启.若是系统杀掉了你的服务,一旦资源变得可能,系统将尽量重启它(但这仍然依赖于你从onStartCommand()方法返回的值,后面讨论)。关于系统何时可能会销毁服务的,详细信息请看Processes and Threading文档.
In the following sections, you'll see how you can create each type of service and how to use it from other application components.
在接下来的部分,你将会了解,如何建立各种种服务及怎样从其余的应用使用它。
Declaring a service in the manifest在manifest文档中声明服务
Like activities (and other components), you must declare all services in your application's manifest file.跟活动同样(及其余组件),你必须在你的应用的manifest文件中,声明全部的服务.
To declare your service, add a <service> element as a child of the <application> element. For example:要声明你的服务,须要在<application>元素加入<service>子元素.
<manifest ... >
    <application ... >    
         <service android:name=".ExampleService" />
    </application>
</manifest>
There are other attributes you can include in the <service> element to define properties such as permissions required to start the service and the process in which the service should run. The android:name attribute is the only required attribute—it specifies the class name of the service. Once you publish your application, you should not change this name, because if you do, you might break some functionality where explicit intents are used to reference your service (read the blog post, Things That Cannot Change).
你能够在<service>元素中包含一些其余的属性,来定义像请求开启服务的权限和该服务应该运行的进程。android:name属性是惟一必需要求的属性—它指定了服务的类名.一旦你的应用发布了,你应不要改变这个名字,由于若是你改变了这个名字,可能会破坏那些显式的引用你的服务的功能(读取博文,一些其余不改变的东西Things That Cannot Change)。
See the <service> element reference for more information about declaring your service in the manifest.
更多关于在manifest中声明你的服务的信息,请参考<service> 元素索引.
Just like an activity, a service can define intent filters that allow other components to invoke the service using implicit intents. By declaring intent filters, components from any application installed on the user's device can potentially start your service if your service declares an intent filter that matches the intent another application passes to startService().
就像activity同样,服务也能够经过定义意图过滤器,让其余组件使用隐式意图来调用服务。经过声明意图过滤器,若是你声明的意图过滤器与其余应用传给startService()方法的意图相匹配,则安装在用户设备上的任何应用的组件潜在的可启动你的服务.
If you plan on using your service only locally (other applications do not use it), then you don't need to (and should not) supply any intent filters. Without any intent filters, you must start the service using an intent that explicitly names the service class. More information about starting a service is discussed below.
若是你仅让你的服务在局部使用(其余的应用不能使用它),那么你不须要提供一个意图过滤器。由于没有任何意图过滤器,你必须使用显式的指出服务类名的意图来启动该服务。下面的starting a service 中将详细讨论.
Additionally, you can ensure that your service is private to your application only if you include the android:exported attribute and set it to "false". This is effective even if your service supplies intent filters.
另外,只要你包含了属性,并设为"false",那么就能确保你的服务仅为你的应用私有。这样即便你的服务提供了意图过滤器,但你的服务仍然仅为你的应用私有.
For more information about creating intent filters for your service, see the Intents and Intent Filters document.
关于为服务建立意图过滤器,请看Intents and Intent Filters文档.
Creating a Started Service建立启动服务
A started service is one that another component starts by calling startService(), resulting in a call to the service's onStartCommand() method.
其余组件调用startService()方法,并致使服务的onStartCommand()方法被调用,这就是一个启动的服务。
When a service is started, it has a lifecycle that's independent of the component that started it and the service can run in the background indefinitely, even if the component that started it is destroyed. As such, the service should stop itself when its job is done by calling stopSelf(), or another component can stop it by calling stopService().
当一个服务启动后,它就捅有了独立于开启它的组件的生命周期,而且即便开启它的组件被销毁,它也能够在无限循环的运行在后台。所以当服务的工做处理完成后,它应该本身调用stopSelf()方法结束本身,或者其余的组件调用stopService()方法中止服务。
An application component such as an activity can start the service by calling startService() and passing an Intent that specifies the service and includes any data for the service to use. The service receives this Intent in the onStartCommand() method.
某个应用组件,好比activity,能够将一个包含指定服务及服务要用的任意数据的Intent意图,传给startService()方法,来启动一个服务。该服务将会在onStartCommand()方法中接收到这个Intent意图.
For instance, suppose an activity needs to save some data to an online database. The activity can start a companion service and deliver it the data to save by passing an intent to startService(). The service receives the intent in onStartCommand(), connects to the Internet and performs the database transaction. When the transaction is done, the service stops itself and it is destroyed.
好比,假设一个活动须要保一些存数到在线数据库。这个活动能够把要保存的数据传给startService()方法,来开启一个协助服务,该服务在onStartCommand()方法接收到这个意图,链接到网上,并处理数据库交换。当交换完成,该服务中止它本身并销毁本身.
Caution: A services runs in the same process as the application in which it is declared and in the main thread of that application, by default. So, if your service performs intensive or blocking operations while the user interacts with an activity from the same application, the service will slow down activity performance. To avoid impacting application performance, you should start a new thread inside the service.
注意:默认状况下,服务运行在与应用相同的进程中,而且是在应用的主线程中。因此,当用户与活动的交互操做与服务执行的密集或阻塞操做是在同一个应用时,服务将下降交互的性能。为了避名影响应用的性能,你应为服务开启一个新的线程.
Traditionally, there are two classes you can extend to create a started service:习惯上,继承两个类来启动服务
Service
This is the base class for all services. When you extend this class, it's important that you create a new thread in which to do all the service's work, because the service uses your application's main thread, by default, which could slow the performance of any activity your application is running.
这是全部服务的基类,当你继承这个类时,最重要的是你要开启一个新的线程,在这个线程中处理全部服务操做。由于默认状况下,服务使用你的应用的主线程,这会下降你应用中正在运行的全部活动的性能。
IntentService
This is a subclass of Service that uses a worker thread to handle all start requests, one at a time. This is the best option if you don't require that your service handle multiple requests simultaneously. All you need to do is implement onHandleIntent(), which receives the intent for each start request so you can do the background work.
这是一个Service类的子类,它使用一个工人线程处理全部发起的服务,一次处理一个。若是你不想让你的线程同时处理多个服务,这是最好的选择。你所须要作的全部事情,是实现onHandleIntent()方法。在这个实现中接收每一个发起请求的意图,以便你作些后台处理。
The following sections describe how you can implement your service using either one for these classes.
下面描述了,怎样使用某个这些类实现你的服务。
Extending the IntentService class继承意图服务类
Because most started services don't need to handle multiple requests simultaneously (which can actually be a dangerous multi-threading scenario), it's probably best if you implement your service using the IntentService class.
由于多数启动的服务不须要同时处理多个请求(实际上同时处理多个请求的状况是多线程),因此可能用IntentService这个类,来实现你的服务是最好的选择。
The IntentService does the following:这个类处理以下事情:
Creates a default worker thread that executes all intents delivered to onStartCommand() separate from your application's main thread.
建立一个独立于你应用的主线程的工做线程,在这个工做线程中处理全部传给onStartCommand()方法的意图
Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have to worry about multi-threading.
建立一个工做队列,每次传一个意图给你的onHandleIntent()方法实现,因此你永没必要担忧多线程的问题
Stops the service after all start requests have been handled, so you never have to call stopSelf().
在全部发起的请求处理完后中止服务,因此你永没必要调用stopSelf()方法.
Provides default implementation of onBind() that returns null.
提供一个默认的onBind()方法的实现,该实现返回null.
Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation.
提供一个默认的onStartCommand()方法的实现,来发送意图到工做队列,而后(由工做队列)发到你的onHandleIntent()方法的实现
All this adds up to the fact that all you need to do is implement onHandleIntent() to do the work provided by the client. (Though, you also need to provide a small constructor for the service.)
全部这些都基于:实现onHandleIntent()方法,来处理客户端的请求的工做。(所以,你还须要为服务提供一个小构造器).
Here's an example implementation of IntentService:
public class HelloIntentService extends IntentService { android

  /**
   * A constructor is required, and must call the super IntentService(String)
   * constructor with a name for the worker thread.
   */
  public HelloIntentService() {
      super("HelloIntentService");
  } 数据库

  /**
   * The IntentService calls this method from the default worker thread with
   * the intent that started the service. When this method returns, IntentService
   * stops the service, as appropriate.
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() &lt; endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}
That's all you need: a constructor and an implementation of onHandleIntent().
If you decide to also override other callback methods, such as onCreate(), onStartCommand(), or onDestroy(), be sure to call the super implementation, so that the IntentService can properly handle the life of the worker thread.
全部你须要作的是:一个构造器和一个onHandleIntent()方法的实现.
若是你还想要复写其余的回调方法,好比onCreate(), onStartCommand(), onDestroy(),。确保调用了超类实现,以便IntentService类能够正确处理工做线程的生命周期.
For example, onStartCommand() must return the default implementation (which is how the intent gets delivered to onHandleIntent()):
好比,onStartCommand()方法必须返回默认实现(这是意图传递到onHandleIntent()方法的途径)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
    return super.onStartCommand(intent,flags,startId);
}
Besides onHandleIntent(), the only method from which you don't need to call the super class is onBind() (but you only need to implement that if your service allows binding).
除了onHandleIntent()方法以外,onBind()方法是惟一不须要调用的超类的方法(但若是你的服务容许邦定,你只需实现它)
In the next section, you'll see how the same kind of service is implemented when extending the base Service class, which is a lot more code, but which might be appropriate if you need to handle simultaneous start requests.
在下面的部分,你将明白当继承了Service基类时,怎样实现相同的服务;这种方代码稍多一些,可是若是须要处理同时发起的多个请求,这种方式可能理适合您。
Extending the Service class继承服务Service类
As you saw in the previous section, using IntentService makes your implementation of a started service very simple. If, however, you require your service to perform multi-threading (instead of processing start requests through a work queue), then you can extend the Service class to handle each intent.
就如上面你所看到的,使用IntentService类,你能够简单的启动服务。但,若要求你的服务处理多线程(不是用一个工做队列来处理启动请求),那么能够继承Service类来处理每一个意图.
For comparison, the following example code is an implementation of the Service class that performs the exact same work as the example above using IntentService. That is, for each start request, it uses a worker thread to perform the job and processes only one request at a time.
经过比较,下面的例子是实现Service类,与上面使用IntentService类处理的工做彻底相同。对于每一个发起的请求,它使用一个工做线程执行工做,而且每次只处理一个.
public class HelloService extends Service {
  private Looper mServiceLooper;
  private ServiceHandler mServiceHandler; 安全

  // Handler that receives messages from the thread
  private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
          super(looper);
      }
      @Override
      public void handleMessage(Message msg) {
          // Normally we would do some work here, like download a file.
          // For our sample, we just sleep for 5 seconds.
          long endTime = System.currentTimeMillis() + 5*1000;
          while (System.currentTimeMillis() &lt; endTime) {
              synchronized (this) {
                  try {
                      wait(endTime - System.currentTimeMillis());
                  } catch (Exception e) {
                  }
              }
          }
          // Stop the service using the startId, so that we don't stop
          // the service in the middle of handling another job
          stopSelf(msg.arg1);
      }
  } 网络

  @Override
  public void onCreate() {
    // Start up the thread running the service.  Note that we create a
    // separate thread because the service normally runs in the process's
    // main thread, which we don't want to block.  We also make it
    // background priority so CPU-intensive work will not disrupt our UI.
    HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
    thread.start();
    // Get the HandlerThread's Looper and use it for our Handler
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
  } 多线程

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); app

      // For each start request, send a message to start a job and deliver the
      // start ID so we know which request we're stopping when we finish the job
      Message msg = mServiceHandler.obtainMessage();
      msg.arg1 = startId;
      mServiceHandler.sendMessage(msg);
      // If we get killed, after returning from here, restart
      return START_STICKY;
  } less

  @Override
  public IBinder onBind(Intent intent) {
      // We don't provide binding, so return null
      return null;
  }
  @Override
  public void onDestroy() {
    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
  }
}
As you can see, it's a lot more work than using IntentService.如你所见,它比使用IntentService类,要作的事多不少。
However, because you handle each call to onStartCommand() yourself, you can perform multiple requests simultaneously. That's not what this example does, but if that's what you want, then you can create a new thread for each request and run them right away (instead of waiting for the previous request to finish).
然而,由于你可本身处理每一个对onStartCommand()的调用,因此你能够同时执行多个请求。这段例子没有那样作,可是若是你想要那样作,那么能够为每一个请求建立一个新线程,而且以正确的方法运行它。(而不是等到前一个请求执行完成.)
Notice that the onStartCommand() method must return an integer. The integer is a value that describes how the system should continue the service in the event that the system kills it (as discussed above, the default implementation for IntentService handles this for you, though you are able to modify it). The return value from onStartCommand() must be one of the following constants:
注意,方法必须返回一个整数值。这个整数值,描述了在系统杀掉本服务的状况下,系统应该如何继续该服务(如上所讨论的,IntentService类的默认实现为你处理了这个事情,但你也能够修改它)。从onStartCommand()该方法返回的值必须是下面常量中的一个.
START_NOT_STICKY
If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver. This is the safest option to avoid running your service when not necessary and when your application can simply restart any unfinished jobs.
在onStartCommand()返回后,若是系统杀掉了该服务,除非有挂起的意图要传送,系统不重建立服务。这是避免没必要运行你的服务,及你的应用能够简单的从新开始没有完成的工做时的一种安全的选择。
START_STICKY
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.
     在onStartCommand()返回后,若是系统杀掉了该服务,重建立服务并调用onStartCommand()方法,可是不传递最后的意图.而是系统传一个null,给调用的onStartCommand().除非有挂起的意图启动服务,那样的话,这些意图被传送。这适用于类于多媒体播放器的服务,它们不须要执行命令,可是要无限运行并等待工做。
START_REDELIVER_INTENT
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand() with the last intent that was delivered to the service. Any pending intents are delivered in turn. This is suitable for services that are actively performing a job that should be immediately resumed, such as downloading a file. For more details about these return values, see the linked reference documentation for each constant.
在onStartCommand()返回后,若是系统杀掉了该服务,从新建立服务并调用onStartCommand()方法,并将最后一个传给服务的意图传给onStartCommand()方法。这适合那要当即恢复并积极主动执行工做的服务,好比下载文件。关于这个返回值的详细状况,请看每一个常量连接引用的文档
Starting a Service启动服务
You can start a service from an activity or other application component by passing an Intent (specifying the service to start) to startService(). The Android system calls the service's onStartCommand() method and passes it the Intent. (You should never call onStartCommand() directly.)
你能够经过将一个Intent意图传给startService()方法,从某个活动或其余应用组件中启一个服务.Android系统将调用服务的onStartCommand()方法,并将一个Intent意图传给它。(你应该永远不要直接调用onStartCommand()方法)
For example, an activity can start the example service in the previous section (HelloSevice) using an explicit intent with startService():
例如,一个活动能够给startService()方法一个显式意图,启动前的例子服务程序.
Intent intent = new Intent(this, HelloService.class);
startService(intent);
The startService() method returns immediately and the Android system calls the service's onStartCommand() method. If the service is not already running, the system first calls onCreate(), then calls onStartCommand().
startService()方法当即返回,而且系统会调用onStartCommand()方法,若是服务没有正在运行,系统首先调用onCreate(),方法,而后调用onStartCommand()方法。
If the service does not also provide binding, the intent delivered with startService() is the only mode of communication between the application component and the service. However, if you want the service to send a result back, then the client that starts the service can create a PendingIntent for a broadcast (with getBroadcast()) and deliver it to the service in the Intent that starts the service. The service can then use the broadcast to deliver a result.
若是服务尚未邦定,使用startService()方法传送意图,是应用组件与服务通讯的惟一模式.然而,若是你想要服务返回一个结果,那么启动服务的客户端,能够建立一个用于广播的PendingIntent挂起意图,而且在启动服务的Intent意图中,将这个挂起意图传给服务.而后服务就能够用这个广播来传递一个结果.
Multiple requests to start the service result in multiple corresponding calls to the service's onStartCommand(). However, only one request to stop the service (with stopSelf() or stopService()) is required to stop it.
对启动服务的多个请求,会相应的致使屡次调用服务的方法。然而,只有一个请求中止服务(stopSelf() or stopService())请求中止它。
Stopping a service中止某个服务
A started service must manage its own lifecycle. That is, the system does not stop or destroy the service unless it must recover system memory and the service continues to run after onStartCommand() returns. So, the service must stop itself by calling stopSelf() or another component can stop it by calling stopService().
一个启动的服务必须能管理它本身的生命周期。那就是,除非系统要收复系统内存,系统不中止和销毁服务,而且在onStartCommand()方法返回后能继续运行.因此,服务必须调用stopSelf()方法中止本身,或者其余组件调用stopService()方法中止它.
Once requested to stop with stopSelf() or stopService(), the system destroys the service as soon as possible.
一旦用stopSelf()或stopService()方法,发出中止请求,系统将尽量快的中止服务.
However, if your service handles multiple requests to onStartCommand() concurrently, then you shouldn't stop the service when you're done processing a start request, because you might have since received a new start request (stopping at the end of the first request would terminate the second one). To avoid this problem, you can use stopSelf(int) to ensure that your request to stop the service is always based on the most recent start request. That is, when you call stopSelf(int), you pass the ID of the start request (the startId delivered to onStartCommand()) to which your stop request corresponds. Then if the service received a new start request before you were able to call stopSelf(int), then the ID will not match and the service will not stop.
然而,若是你的服务正在同时处理多个发给onStartCommand()方法的请求,那么你不该该在处理完一个发起的请求(a start request)后中止服务,由于你可已接到一个新的发起请求(在第一个请求以后中止可能会终结第二个请求).为了不这个问题,你能够用stopSelf(int)方法,确保你的中止服务的请求,老是基于最后发起的请求的。那就是,当你调用stopSelf(int)方法时,传一个请求中止相应的服务的ID。而后若是服务在你能调用stopSelf(int)方法以前,接收到一个新发起的请求,那么这个ID将不会匹配,而且服务将不中止.
Caution: It's important that your application stops its services when it's done working, to avoid wasting system resources and consuming battery power. If necessary, other components can stop the service by calling stopService(). Even if you enable binding for the service, you must always stop the service yourself if it ever received a call to onStartCommand().
注意:当服务处理完工做后,你的应用中止它很重要,以免浪费系统资源和消耗电池。若是必要的话,其余组件能够用stopService()方法中止它。即便你容许邦定,但若是你曾经收到一个onStartCommand()调用,你必须老是本身中止服务.
For more information about the lifecycle of a service, see the section below about Managing the Lifecycle of a Service.
关于服务的生命周期限,看下面关于Managing the Lifecycle of a Service管理服务的生命周期.
Creating a Bound Service建立一个邦定服务
A bound service is one that allows application components to bind to it by calling bindService() in order to create a long-standing connection (and generally does not allow components to start it by calling startService()).
邦定服务是指:容许应用组件调用bindService()方法邦定一个服务,以创建长期的联接。(而且通常不容许组件调用startService()方法开启它。)
You should create a bound service when you want to interact with the service from activities and other components in your application or to expose some of your application's functionality to other applications, through interprocess communication (IPC).
当你想要活动,及应用中的其余组件,与服务之间进行交互操做时,或者经过进程间通讯,把你的应用的功能,公开给其余应用时,你应建立一个邦定的服务。
To create a bound service, you must implement the onBind() callback method to return an IBinder that defines the interface for communication with the service. Other application components can then call bindService() to retrieve the interface and begin calling methods on the service. The service lives only to serve the application component that is bound to it, so when there are no components bound to the service, the system destroys it (you do not need to stop a bound service in the way you must when the service is started through onStartCommand()).
要建立一个邦定的服务,你必须实现onBind()回调方法,返回一个IBinder,它定义了与服务通讯的接口。其余应用组件而后调用bindService()方法取回接口并….只有服务于邦到它的应用组件时,服务才存在,因此当没有组件邦定到服务时,系统销毁它(你不须要中止一个邦定的服务,但当服务是经过onStartCommand()方法启动时,你必须中止它).
To create a bound service, the first thing you must do is define the interface that specifies how a client can communicate with the service. This interface between the service and a client must be an implementation of IBinder and is what your service must return from the onBind() callback method. Once the client receives the IBinder, it can begin interacting with the service through that interface.
要建立一个邦定的服务,首要的事情是,你必须定义与服务通讯的接口。服务与客户端之间的这个接口,必须是一个的IBinder实现,而且这就是为何你的服务必须从onBind()方法中返回它的缘由.
Multiple clients can bind to the service at once. When a client is done interacting with the service, it calls unbindService() to unbind. Once there are no clients bound to the service, the system destroys the service.
多个客户端能够同时邦定到一个服务。当某个客户端处理完与服务的交互工做时,它能够调用unbindService()松邦.一旦没有客户端邦定到该服务,系统就销毁该服务.
There are multiple ways to implement a bound service and the implementation is more complicated than a started service, so the bound service discussion appears in a separate document about Bound Services.
有许多方法去实现邦定服务,而且它有实现比启动服务复杂得多,因此单独在Bound Services中讨论邦定服务的。
Sending Notifications to the User发送通知给用户
Once running, a service can notify the user of events using Toast Notifications or Status Bar Notifications.
当运行时,一个服务能够用Toast Notifications 或Status Bar Notifications通知用户事件.
A toast notification is a message that appears on the surface of the current window for a moment then disappears, while a status bar notification provides an icon in the status bar with a message, which the user can select in order to take an action (such as start an activity).
吐司通知(弹出的窗口像吐司面包)是一个出如今当前窗口表面的一个消息,显示一下子而后消失,而状态条消息提一个带有消息的icon显示在状态条上,用户能够选择它,执行一个动做(好比启动一个活动)
Usually, a status bar notification is the best technique when some background work has completed (such as a file completed downloading) and the user can now act on it. When the user selects the notification from the expanded view, the notification can start an activity (such as to view the downloaded file).
一般,当一些后台操做完后时,使用状态条通知是最好的技术(好比一个文件完成下载),而且用户能够对它执行动做。当用户从它的扩展视图中选取该通知,该通知能够启动一个活动(好比看下载文件)
See the Toast Notifications or Status Bar Notifications developer guides for more information.
详细信息,请看Toast Notifications 或者 Status Bar Notifications开发指南
Running a Service in the Foreground运行一个前台服务
A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the "Ongoing" heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
一个前台服务是用户经过综合考虑后特别关心的一个服务,而且在缺乏内存时,不是系统要杀掉的候选者。一个前台服务必须为状态条提供一个通知,放在"Ongoing"头下,这个意思是这个通知不能被扔掉,除非服务被中止或者被移到后台.
For example, a music player that plays music from a service should be set to run in the foreground, because the user is explicitly aware of its operation. The notification in the status bar might indicate the current song and allow the user to launch an activity to interact with the music player.
好比,一个从服务播放音乐的播放器,应该被设置放到前台,由于用户很关心它的操做。在状态条上的通知可能指示当前的歌曲,而且容许用户运行一个活动与音乐播放器交互.
To request that your service run in the foreground, call startForeground(). This method takes two parameters: an integer that uniquely identifies the notification and the Notification for the status bar. For example:
要请求你的服务运行到前台,调用startForeground().方法。这个方法带两个参数:一个标识通知器的整数及状态条的Notification通知器.例如:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
        System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
        getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION, notification);
To remove the service from the foreground, call stopForeground(). This method takes a boolean, indicating whether to remove the status bar notification as well. This method does not stop the service. However, if you stop the service while it's still running in the foreground, then the notification is also removed.
要把该服务从前台移除,调用stopForeground()方法.这个方法带有一个boolean值,表示是否同时将通知也从状态条上移除。这个方法不中止服务。可是,若是你中止一个在前台正在运行的服务,那么该通知将也被移除.
Note: The methods startForeground() and stopForeground() were introduced in Android 2.0 (API Level 5). In order to run your service in the foreground on older versions of the platform, you must use the previous setForeground() method—see the startForeground() documentation for information about how to provide backward compatibility.
注意:startForeground()和stopForeground()这个两方法是在Android 2.0中介绍进来的。为了让你的服务能够旧版本的平台上运行,你必须使用之前的setForeground()方法。关于向后兼容请看startForeground()文档.
For more information about notifications, see Creating Status Bar Notifications.
关于建立通知器,请看Creating Status Bar Notifications.
Managing the Lifecycle of a Service管理服务生命周期
The lifecycle of a service is much simpler than that of an activity. However, it's even more important that you pay close attention to how your service is created and destroyed, because a service can run in the background without the user being aware.
服务的生命周期比活动的简单的多。可是,因为服务可运行在后台,而且用户着察不到,因此更进一步了解服务的建立和销毁就显得更加剧要。
The service lifecycle—from when it's created to when it's destroyed—can follow two different paths:
服务的生命周期—从建立到结束—能够从以下两条路径:
A started service 启动的服务
The service is created when another component calls startService(). The service then runs indefinitely and must stop itself by calling stopSelf(). Another component can also stop the service by calling stopService(). When the service is stopped, the system destroys it..
该服务是其余组件调用startService()方法建立的。而后服务无限运行而且必须本身调用stopSelf()方法中止本身。其余组也能够调用stopService()方法中止它.当服务中止,系统销毁它..
A bound service 邦定的服务
The service is created when another component (a client) calls bindService(). The client then communicates with the service through an IBinder interface. The client can close the connection by calling unbindService(). Multiple clients can bind to the same service and when all of them unbind, the system destroys the service. (The service does not need to stop itself.)
该服务是其余组件调用bindService()方法开启的.客户端而后经过IBinder接口与服务通讯,客户端能够调用unbindService()方法断开联接。多个客户端能够邦定到同一个服务而且当全部的客户端松邦后,系统销毁该服务(服务不须要本身中止本身)
These two paths are not entirely separate. That is, you can bind to a service that was already started with startService(). For example, a background music service could be started by calling startService() with an Intent that identifies the music to play. Later, possibly when the user wants to exercise some control over the player or get information about the current song, an activity can bind to the service by calling bindService(). In cases like this, stopService() or stopSelf() does not actually stop the service until all clients unbind.
这两种方法并非彻底分开的。你能够邦定一个服务到一个用startService()方法开启的服务.好比,经过调用一个带有指定播放音乐的Intent意图的startService()方法,开启一个后台音乐播放服务.后来,用户可能想要对播放器作一些控制或者想获取关于当前音乐的信息,一个活动能够调用bindService()方法邦定到该服务.在像这样的状况下,stopService()或者stopSelf()方法不能真正中止服务,除非全部的客户端解除邦定.
Implementing the lifecycle callbacks实现生命周期回调方法
Like an activity, a service has lifecycle callback methods that you can implement to monitor changes in the service's state and perform work at the appropriate times. The following skeleton service demonstrates each of the lifecycle methods:
和活动同样,服务有生命周期回调方法,你能够实现这些方法监视服务状态的改变,并在适当的时候处理一些工做。下面的服务骨架代码演示了生命周期的每一个回调方法.
public class ExampleService extends Service {
    int mStartMode;       // indicates how to behave if the service is killed
    IBinder mBinder;      // interface for clients that bind
    boolean mAllowRebind; // indicates whether onRebind should be used ide

    @Override
    public void onCreate() {
        // The service is being created
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // The service is starting, due to a call to startService()
        return mStartMode;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // A client is binding to the service with bindService()
        return mBinder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        // All clients have unbound with unbindService()
        return mAllowRebind;
    }
    @Override
    public void onRebind(Intent intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }
    @Override
    public void onDestroy() {
        // The service is no longer used and is being destroyed
    }
}
Note: Unlike the activity lifecycle callback methods, you are not required to call the superclass implementation of these callback methods.不像活动的生命周期的回调方法,你没必要要去调用超类的这些回调方法的实现
Figure 2. The service lifecycle. The diagram on the left shows the lifecycle when the service is created with startService() and the diagram on the right shows the lifecycle when the service is created with bindService().
图2.服务的生命周期,图的左边演示的是用startService()方法建立的服务的生命周期,图的右边演示的是用bindService()方法建立的服务的生命周期.
By implementing these methods, you can monitor two nested loops of the service's lifecycle:
经过实现这些方法,你能够监视到服务的生命周期的两个嵌套循环:
The entire lifetime of a service happens between the time onCreate() is called and the time onDestroy() returns. Like an activity, a service does its initial setup in onCreate() and releases all remaining resources in onDestroy(). For example, a music playback service could create the thread where the music will be played in onCreate(), then stop the thread in onDestroy().
The onCreate() and onDestroy() methods are called for all services, whether they're created by startService() or bindService().
服务的整个的生命时间,发生在onCreate()方法被调用时和onDestroy()方法返回时.与活动同样,服务在onCreate()方法中执行初始化操做,并在onDestroy()方法中释放保持的资源.好比,音乐回放服务可能在onCreate()方法中建立播放音乐线程,并在onDestroy()方法中中止线程.不管它们由startService() 或者bindService()建立,全部服务都会调用onCreate()和onDestroy()方法.
The active lifetime of a service begins with a call to either onStartCommand() or onBind(). Each method is handed the Intent that was passed to either startService() or bindService(), respectively.
服务的激活生命时间,开始于对onStartCommand()方法或onBind()方法的调用.每一个方法相应的处理传给startService()方法或者bindService()方法的Intent意图.
If the service is started, the active lifetime ends the same time that the entire lifetime ends (the service is still active even after onStartCommand() returns). If the service is bound, the active lifetime ends when onUnbind() returns.
若是服务是开启的,该激活生命时间的结束时间同整个生命时间同样(即便onStartCommand()方法返回了,服务仍然是激活的)。若是服务是结束邦定的,激活的生命时间结束于onUnbind()方法返回.
Note: Although a started service is stopped by a call to either stopSelf() or stopService(), there is not a respective callback for the service (there's no onStop() callback). So, unless the service is bound to a client, the system destroys it when the service is stopped—onDestroy() is the only callback received.
注意:虽然一个开启的服务可能经过调用stopSelf()或者stopService()方法中止,但服务没有与此相应的回调方法(没有onStop()回调)。除非服务邦定到一个客户端,不然当服务中止时系统就销毁它—onDestroy() 方法是惟一回调接收方法.
Figure 2 illustrates the typical callback methods for a service. Although the figure separates services that are created by startService() from those created by bindService(), keep in mind that any service, no matter how it's started, can potentially allow clients to bind to it. So, a service that was initially started with onStartCommand() (by a client calling startService()) can still receive a call to onBind() (when a client calls bindService()).
图2说明了一个服务的典型回调方法,虽然该图把服务以由方法建立startService() 的和由bindService()方法建立的分开了,但请记住,无论服务是如何建立的,都能容许客户端邦定到它。因此,用onStartCommand()方法初始化的服务(客户端调用startService()),仍能接收一个onBind()方法的调用。
For more information about creating a service that provides binding, see the Bound Services document, which includes more information about the onRebind() callback method in the section about Managing the Lifecycle of a Bound Service.
关于建立提供邦定的服务的详细信息,看Bound Services文档,在那里的Managing the Lifecycle of a Bound Service一节,有更多关于onRebind() 回调方法的更详细信息. oop

相关文章
相关标签/搜索