zoukankan      html  css  js  c++  java
  • Android Service

    Android Service

    Service 是一种运行在后台没有界面的组件,可以执行一些需要长期运行的过程。

    需要注意的是,service组件本身并不会新建一个进程或者线程来执行任务,service组件运行在它所属App的主线程中。因此,通常需要在service组件中新建一个线程来执行耗时的任务。

    Service 与 new Thread的区别

    Service 组件用于当用户没有与app进行交互时在后台执行一些操作,而在Activity中new Thread执行操作需要考虑Activity的生命周期,对于只在与用户交互时才执行的耗时操作应该采用new Thread的方式。

    Service可以分为两种类型:

    • started service

    started service由其他组件调用startService()方法来启动,一经启动便会一直运行下去,直到有其他某个组件调用stopService()方法请求停止或者该service组件自己调用stopSelf()方法终止自己的运行。

    started service通常用于执行一些不需要返回结果的操作,操作执行完成之后自己调用stopSelf()方法结束。

    • bound service

    bound service由其他组件调用bindService()方法来启动,一个bound service可以被多个组件bind,bind该service的组件可以通过调用unbind()方法结束与service的通信,当bind该bound service的所有组件都结束了与它之间的通信,该bound service的生命周期也就随之结束。

    bound service通常用于需要返回执行结果或者执行过程中需要进行交互的操作,其他组件可以通过IBinder或者Messenger与bound service进行通信。

    started service 与 bound service之间并没有十分明显的界限,在实现上的区别只体现在是否实现相关的回调函数,started service主要实现onStartCommand()方法,bound service主要实现onBind()方法和onUnbind()方法。

    创建Service组件

    • 从Service类或者其子类IntentService类继承,定义Service组件的实现类。

      IntentService类是Service类的子类,它使用一个worker线程和一个队列处理所有Intent请求,只需覆盖实现其onHandleIntent()方法来处理一个Intent请求,当所有的Intent请求都处理完后,IntentService会自动结束运行,无需使用者调用stopSelf()方法来结束。
      Service类则更为灵活,可以自定义使用单线程或者多个线程对Intent请求进行处理。

    • 像Activity一样,需要在AndroidManifest.xml文件中声明Service组件。

    Service的生命周期

    • started service

      onCreate(),创建Service组件时回调,只被调用一次。

      onStartCommand(),其他组件调用startService()方法请求启动Service组件时回调该方法。

      该Service组件调用stopSelf()方法或者其他组件调用stopService()方法。

      onDestroy(),该Service组件的生命周期即将结束时回调,可以在该方法中做一些资源的回收工作。

    • bound service

      onCreate(),创建Service组件时回调。

      onBind(),其他组件调用bindService()方法请求bind到该Service组件时回调该方法。

      onUnbind(),所有其他组件都解除与该Service的bind后回调该方法。

      onDestroy(),该Service的生命周期即将结束。

    • 如前所述,started service和bound service之间的界限不明显。 如果bound service组件也实现了onStartCommand()方法,那么就可以接收startService()方法的intent请求,它的生命周期在onUnbind()方法之后不会直接进入onDestroy,而是需要调用stopSelf()方法或者stopService()方法来结束其生命周期。

    • 当系统发现内存资源不够用时,可能会主动kill掉还在运行的Service组件。Service组件可以通过调用startForeground()方法来将自己设置成foreground模式,处于foreground模式的Service组件不会被系统主动kill掉。

    Bound Service的实现步骤

    • 继承Binder类

    bound service组件实现onBind()方法,返回IBinder接口对象。IBinder接口中定义了其他组件与bound service组件进行通信的方法接口,可以通过继承Binder类来实现IBinder接口。

    其他组件在调用bindService()方法时需要提供ServiceConnection对象,ServiceConnection对象中包含一个回调方法onServiceConnected(),当bound service组件成功与之建立连接后,会回调onServiceConnected方法返回IBinder接口对象。

    这种方式适用于bound service组件只会被同一个app中的其他组件使用,因为IBinder需要将与Service组件通信的方法接口暴露给其他组件,只有Service组件和其他组件运行在同一个虚拟机(即同一个进程)中才可以。

    • 使用Messenger类

    bound service组件中实现一个Handler接口,在Handler接口的handleMessage()方法中根据消息类型来处理来自其他组件的请求。bound service组件还持有一个Messenger对象,该Messenger对象持有Handler的引用,并且在onBind()方法中返回的IBinder对象也是由该Messenger对象创建的。

    其他组件也持有一个Messenger对象,该Messenger对象根据ServiceConnection对象中返回的IBinder对象构造而来。其他组件可以通过该Messenger对象的send()方法向Service组件发送指定消息类型的Message信息。

    这种方式向其他组件屏蔽了IBinder接口的具体通信方法,而是根据双方约定好的消息类型通过Messenger对象来进行通信。可以用于Service组件与其他组件之间的跨进程通信。

    • AIDL

    Messenger类是基于AIDL的方式实现的,Messenger类会使用队列来保存其他组件发来的消息,使用单个工作线程,每次只提供一个消息给Handler对象处理。

    如果需要Service组件拥有同时处理多个消息的能力,则需要使用AIDL的方式来实现。

  • 相关阅读:
    洛谷 P1231 教辅的组成
    BZOJ 2190: [SDOI2008]仪仗队
    Codeforces GYM 100741A . Queries
    COGS 1298. 通讯问题
    洛谷 P2604 [ZJOI2010]网络扩容
    codevs 1227 方格取数 2
    codevs 1004 四子连棋
    洛谷 P2319 [HNOI2006]超级英雄
    洛谷 P2153 [SDOI2009]晨跑
    插入排序
  • 原文地址:https://www.cnblogs.com/jqctop1/p/5543949.html
Copyright © 2011-2022 走看看