Android Service是一个可以在后台执行长时间运行操作而不提供用户界面的应用组件,它分为两种工作状态,一种是启动状态,主要用于执行后台计算;另一种是绑定状态,主要用于其他组件和Service的交互。需要注意的两点:

  • 两种状态是共存的,即Service可以是启动状态也可以同时是绑定状态
  • 防止ANR风险,主线程运行的Service在执行耗时操作,则应在服务内创建新线程来完成这项工作,这可以降低发生“应用无响应”(ANR) 错误的风险。

使用

要创建服务,您必须创建 Service 的子类。在实现中,需要重写一些回调方法,以处理服务生命周期的某些关键方面并提供一种机制将组件绑定到服务。

public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

Service需要重写重要的回调方法有以下几个

  • onStartCommand():通过调用 startService() 请求启动服务时,系统将调用此方法,bindService无需实现该方法
  • onBind():通过调用 bindService() 与服务绑定(例如执行 RPC)时,系统将调用此方法,通过返回 IBinder 提供一个接口,供客户端用来与服务进行通信
  • onCreate():首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或 onBind() 之前)
  • onDestroy():当服务不再使用且将被销毁时,系统将调用此方法。服务应该实现此方法来清理所有资源,如线程、注册的侦听器、接收器等。 这是服务接收的最后一个调用

像Activity(以及其他组件)一样,您必须在应用AndroidManifest.xml清单文件中声明所有服务

<service android:name=".MyService"/>

通过Context启动一个Service,这会导致对 onStartCommand() 的调用,则服务将一直运行,直到服务使用 stopSelf() 自行停止运行,或由其他组件通过调用 stopService() 停止,如下所示

startService(new Intent(this, MyService.class));

但在Android8.0的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,则该函数将引发一个 IllegalStateException。 新的 Context.startForegroundService() 函数将启动一个前台服务。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(intent);
} else {
    startService(intent);
}

并且在在service里再调用startForeground方法,不然就会出现ANR

context.startForeground(SERVICE_ID, builder.getNotification());

通过Context绑定一个Service,且未调用 onStartCommand(),则服务只会在该组件与其绑定时运行,一旦该服务与所有客户端之间的绑定全部取消,系统便会销毁它,如下所示

bindService(new Intent(this, MyService.class), connection, BIND_AUTO_CREATE);

注意:系统内存不足时,Android会强制停止优先级低的Service来提供内存给Activity使用,但持有Activity的Service可能不会终止,或者前台运行的Service几乎永远不会终止。

Service启动

首先我们先看下Service的类的调用流程



相关类说明

  • ContextWrapper:代理Context的实现,简单地将其所有调用委托给另一个Context
  • ContextImpl:Context API的通用实现,为Activity和其他应用程序组件提供基本上下文对象
  • ActivityManager:此类提供有关活动,服务和包含过程的信息和交互
  • IActivityManager.aidl:用于与ActivityManagerService交谈的系统专用API,提供了从应用程序返回到活动管理器的调用
  • ActivityManagerService:负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作
  • ActivityThread:管理应用程序进程中主线程的执行,根据ActivityManager请求调度和执行Activitys、broadcasts和其他操作
  • ApplicationThread:ActivityThread内部类,IApplicationThread.aidl的具体实现,提供给ActivityManager,ActivityManager通过它告知应用程序将要做的事
  • IApplicationThread:用于与应用程序通信的系统专用API

Service最终创建需要需要通过Handler进行消息发送来实现创建,并把创建好的servic存储在ArrayMap中。接下来看下Service的生命周期是怎样的。



需要注意的是,在整个生命周期内,只有startCommand()能被多次调用。其他方法只能被调用一次。

Service绑定

Service绑定跟Service的启动了类调用流程基本一致,只是相关方法改为bind,但其最后会调用ServiceConnection对象的onServiceConnected方法。接下来看下Service的生命周期是怎样的



但其有一个特性,多次绑定同一个Service时,Service的onBind方法只会执行一次,除非Service被终止了。

Android Service解析的更多相关文章

  1. Android Service完全解析,关于服务你所需知道的一切(下)

    转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在上一篇文章中,我们学习了Android Service相关的许多重要 ...

  2. Android Service完全解析,关于服务你所需知道的一切(上)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...

  3. 【转】Android Service完全解析,关于服务你所需知道的一切(下) ---- 不错

    原文网址:http://blog.csdn.net/guolin_blog/article/details/9797169 转载请注册出处:http://blog.csdn.net/guolin_bl ...

  4. [转]Android Service完全解析,关于服务你所需知道的一切

      目录(?)[+] Android Service完全解析,关于服务你所需知道的一切(上) 分类: Android疑难解析2013-10-31 08:10 6451人阅读 评论(39) 收藏 举报 ...

  5. (转) Android Service完全解析,关于服务你所需知道的一切(上)

    相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Service作为Android四大组件之一,在每一个应用程序 ...

  6. Android Service完全解析,关于服务你所需知道的一切(下) (转载)

    转自:http://blog.csdn.net/guolin_blog/article/details/9797169 转载请注册出处:http://blog.csdn.net/guolin_blog ...

  7. Android Service完全解析,关于服务你所需知道的一切(上) (转载)

    转自:http://blog.csdn.net/guolin_blog/article/details/11952435 转载请注明出处:http://blog.csdn.net/guolin_blo ...

  8. Android Service完全解析(上)

    转载:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Androi ...

  9. Android Service完全解析,关于服务你所需知道的一切(上)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...

随机推荐

  1. 使用sklearn估计器构建K-Means聚类模型

    实例要求:以sklearn库自带的iris数据集为例,使用sklearn估计器构建K-Means聚类模型,并且完成预测类别功能以及聚类结果可视化. 实例代码: import pandas as pd ...

  2. JAVA泛型实现原理

    1. Java范型时编译时技术,在运行时不包含范型信息,仅仅Class的实例中包含了类型参数的定义信息.泛型是通过java编译器的称为擦除(erasure)的前端处理来实现的.你可以(基本上就是)把它 ...

  3. php中的一些不常见的问题foreach/in_array[开发篇]

    php在开发效率很高,这是无可厚非的,但是却是在牺牲执行效率的.php数组功能非常强大,但是也要多加考虑,多试几种情况情况,以防万一,这里,我就简单的说两个遇到的坑,以后如果有发现更多的,再补上吧! ...

  4. 【code block】局部代码块+构造代码块+静态代码块

    1.局部代码块 位置:位于类的方法中 表示方法:{} 作用:控制变量的生命周期,减少内存消耗 demo: public class LocalCode { public static void mai ...

  5. Java高阶回调,回调函数的另一种玩法

    工具类package com.sctek; import java.lang.reflect.Field; import android.os.CountDownTimer;import androi ...

  6. Jenkins可用环境变量以及使用方法

    Jenkins可用环境变量以及使用方法

  7. JS中如何理解浮点数?

    本文由云+社区发表 相信大家在平常的 JavaScript 开发中,都有遇到过浮点数运算精度误差的问题,比如 console.log(0.1+0.2===0.3)// false.在 JavaScri ...

  8. mysql年初至今聚合

    年初至今聚合和滑动聚合类似,不同的地方仅在于统计的仅为当前一年的聚合.唯一的区别体现在下限的开始位置上.在年初至今的问题中,下限为该年的第一天,而滑动聚合的下限为N个月的第一天.因此,年初至今的问题的 ...

  9. 【leet-code】542. 01 矩阵

    题目描述 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 0 1 0 ...

  10. openssl dhparam(密钥交换)

    openssl系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html openssl dhparam用于生成和管理dh文件.dh(Diffie-H ...