学习service

来源:互联网 发布:影响力 知乎 编辑:程序博客网 时间:2024/06/10 23:27
Started

A service is "started" when an application component (such as an activity) starts it bycallingstartService(). Once started, a servicecan 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, theservice should stop itself



Bound
A service is "bound" when an application component binds to it by calling bindService(). A bound service offers a client-serverinterface that allows components to interact with the service, send requests, get results, and evendo so across processes with interprocess communication (IPC). A bound service runs only as long asanother 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.
Caution: A service runs in themain thread of its hosting process—the service doesnot create its own threadand does not run in a separate process (unless you specify otherwise). This meansthat, if your service is going to do any CPU intensive work or blocking operations (such as MP3playback or networking), you should create a new thread within the service to do that work. By usinga separate thread, you will reduce the risk of Application Not Responding (ANR) errors and theapplication's main thread can remain dedicated to user interaction with your activities.


Caution: A services runs in the same process as the applicationin which it is declared and in the main thread of that application, by default. So, if your serviceperforms intensive or blocking operations while the user interacts with an activity from the sameapplication, the service will slow down activity performance. To avoid impacting applicationperformance, 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 thatyou create a new thread in which to do all the service's work, because the service uses yourapplication's main thread, by default, which could slow the performance of any activity yourapplication is running.
IntentService
This is a subclass of Service that uses a worker thread to handle allstart requests, one at a time. This is the best option if you don't require that your servicehandle multiple requests simultaneously. All you need to do is implement onHandleIntent(), which receives the intent for eachstart request so you can do the background work.

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 youimplement your service using theIntentService class.

The IntentService does the following:

  • Creates a default worker thread that executes all intents delivered to onStartCommand() separate from your application's mainthread.
  • Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have toworry about multi-threading.
  • Stops the service after all start requests have been handled, so you never have to callstopSelf().
  • Provides default implementation of onBind() thatreturns null.
  • Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation.

public class HelloIntentService extends IntentService {  /**    * 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() < endTime) {          synchronized (this) {              try {                  wait(endTime - System.currentTimeMillis());              } catch (Exception e) {              }          }      }  }}


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() < 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();      // 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;  }  @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();   }}



原创粉丝点击