Android学习之服务Service

    服务Service是Android四大组件之一,可以理解为是一个没有界面,在后台运行耗时操作的组件。其他的应用组件可以启动Service,当切换到其他场景是,Service也能够在后台持续运行。一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。
      

     值得一提的是service与activity一样都存在与当前进程的主线程中,所以,一些阻塞UI的操作,比如耗时操作不能放在service里进行,比如另外开启一个线程来处理诸如网络请求的耗时操作。如果在service里进行一些耗CPU和耗时操作,可能会引发ANR警告,这时应用会弹出是强制关闭还是等待的对话框。所以,对service的理解就是和activity平级的,只不过是看不见的,在后台运行的一个组件,这也是为什么和activity同被说为Android的基本组件。

    Service有两种启动方式,一种是直接用startService()启动,一种是绑定bindService()启动。其各自的特点如下:

      通过startService()启动的服务处于“启动的”状态,一旦启动,service就在后台运行,即使启动它的应用组件已经被销毁了。通常started状态的service执行单任务并且不返回任何结果给启动者。通过调用bindService()来启动,一个绑定的service提供一个允许组件与service交互的接口,可以发送请求、获取返回结果,还可以通过夸进程通信来交互(IPC)。绑定的service只有当应用组件绑定后才能运行,多个组件可以绑定一个service,当调用unbind()方法时,这个service就会被销毁了。
    其生命周期如下图所示:

Android学习之服务Service_第1张图片

 

        两种启动service的方式以及他们的生命周期,bind service的不同之处在于当绑定的组件销毁后,对应的service也就被kill了。service的声明周期相比与activity的简单了许多,只要好好理解两种启动service方式的异同就行。

       service生命周期也涉及一些回调方法,这些方法都不用调用父类方法,具体如下:

<span style="font-size:18px;">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  

    @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  
    }  
}</span>


     服务(Service)的停止和启动

        1 .如果service是非绑定的,最终当任务完成时,为了节省系统资源,一定要停止service,可以通过stopSelf()来停止,也可以在其他组件中通过stopService()来停止。
绑定的service可以通过onUnBind()来停止service。
 
       2. 有了 Service 类我们如何启动他呢,有两种方法:

     •Context.startService()      •Context.bindService()

    1). 在同一个应用任何地方调用startService() 方法就能启动Service 了,然后系统会回调Service 类的 onCreate() 以及 onStartCommand() 方法。这样启动的Service 会一直运行在后台,直到Context.stopService() 或者 StopSelf() 方法被调用。另外如果一个Service 已经被启动,其他代码再试图调用startService() 方法,是不会执行onCreate() 的,但会重新执行一次onStartCommand() 。

    2). 另外一种 bindService() 方法的意思是,把这个Service 和调用 Service 的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方法你可以从这里返回一个实现了 IBind 接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service 还没有运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 的onStartCommand()。

   3.总结:
      1). startService()的目的是回调的onStartCommand方法,onCreate() 方法是在Service不存在的时候调用的,如果Service存在(例如之前调用了bindService,那么Service的onCreate方法已经调用了)那么startService()将跳过onCreate() 方法。

     2). bindService()目的是回调onBind()方法,它的作用是在Service和调用者之间建立一个桥梁,并不负责更多的工作(例如一个Service需要连接服务器的操作),一般使用bindService来绑定到一个现有的Service(即通过StartService启动的服务)。

      由于Service 的onStartCommand()方法只有在startService()启动Service的情况下才调用,故使用的onStartCommand()的时候要注意这点。

  4.  与 Service 通信并且让它持续运行
     如果我们想保持和Service 的通信,又不想让Service 随着 Activity 退出而退出呢?你可以先startService() 然后再 bindService() 。当你不需要绑定的时候就执行unbindService() 方法,执行这个方法只会触发Service 的 onUnbind() 而不会把这个 Service 销毁。这样就可以既保持和 Service 的通信,也不会随着 Activity 销毁而销毁了。

    IntentService,首先看下官方文档的说明:IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。而在一般的继承Service里面如果要进行耗时操作就必须另开线程,但是使用IntentService就可以直接在里面进行耗时操作,因为默认实现了一个worker thread。对于异步的startService请求,IntentService会处理完成一个之后再处理第二个。

      看下IntentService的具体实现:

<span style="font-size:18px;">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) {  
             }  
         }  
      }  
  }  
}</span>



 

你可能感兴趣的:(Android学习之服务Service)