Service

第一大要点::千万不要忘了注册,不注册,启动个屁啊

一、Service服务介绍

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

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

二、Service两种启动方式

Service有两种状态,“启动的”和“绑定”

1.两种启动方式的特点:

通过startService()启动的服务处于“启动的”状态,一旦启动,service就在后台运行,即使启动它的应用组件已经被销毁了。通常started状态的service执行单任务并且不返回任何结果给启动者。比如当下载或上传一个文件,当这项操作完成时,service应该停止它本身。

还有一种“绑定”状态的service,通过调用bindService()来启动,一个绑定的service提供一个允许组件与service交互的接口,可以发送请求、获取返回结果,还可以通过夸进程通信来交互(IPC)。绑定的service只有当应用组件绑定后才能运行,多个组件可以绑定一个service,当调用unbind()方法时,这个service就会被销毁了。

2.Service生命周期中的一些方法:
        


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

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

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  
    }  
}

三、服务(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

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

看下IntentService的具体实现:

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) {  
             }  
         }  
      }  
  }  
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值