【Android Service】IntentService
创始人
2025-05-29 03:44:21

IntentService

简单使用

/*** Create by SunnyDay /03/13 17:40:59*/
class DownLoadService : IntentService("FileDownLoadThread") {private val tag = "DownLoadService"override fun onHandleIntent(intent: Intent?) {Log.d(tag, "onHandleIntent Thread info: thread id -> ${Thread.currentThread().id} thread name -> ${Thread.currentThread().name}")Log.d(tag, "开始下载->")Log.d(tag, "下载ing...")SystemClock.sleep(3000)Log.d(tag, "下载完成")}override fun onCreate() {super.onCreate()Log.d(tag, "onCreate")}override fun onStart(intent: Intent?, startId: Int) {super.onStart(intent, startId)Log.d(tag, "onStart")}override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {Log.d(tag, "onStartCommand:startId->$startId")return super.onStartCommand(intent, flags, startId)}override fun onBind(intent: Intent?): IBinder? {Log.d(tag, "onBind")return super.onBind(intent)}override fun onUnbind(intent: Intent?): Boolean {Log.d(tag, "onUnbind")return super.onUnbind(intent)}override fun onDestroy() {super.onDestroy()Log.d(tag, "onDestroy")}
}
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)findViewById
 //第一次开启 D/DownLoadService: onCreateD/DownLoadService: onStartCommand:startId->1D/DownLoadService: onStartD/DownLoadService: onHandleIntent Thread info: thread id -> 62 thread name -> IntentService[FileDownLoadThread]D/DownLoadService: 开始下载->D/DownLoadService: 下载ing...//第二次开启D/DownLoadService: onStartCommand:startId->2D/DownLoadService: onStartD/DownLoadService: 下载完成D/DownLoadService: onHandleIntent Thread info: thread id -> 62 thread name -> IntentService[FileDownLoadThread]D/DownLoadService: 开始下载->D/DownLoadService: 下载ing...D/DownLoadService: 下载完成D/DownLoadService: onDestroy

连续点击两次按钮,可以观察到log:

(1) IntentService的生命周期是这样的

onCreate -> onStartCommand -> onStart -> onHandleIntent -> onDestroy

(2) 系统默认帮我们开启一个子线程,我们可以在onHandleIntent中做一些耗时任务

(3) Service只会被创建一次,多次绑定onStartCommand回调多次

(4) 所有任务完成时onDestroy自动回调

IntentService介绍

  • IntentService是Service的一个子类,内部维护了一个工作线程,他会把所有的任务都放到工作线程中处理。
  • 多次开启IntentService时,每一次的开启的任务都会放到工作线程中处理,当所有的任务完成时他会自动调用stopSelf方法来结束Service
  • onBind方法不会回调
  • onStart方法内部进行了默认实现是IntentService的核心

源码分析

在分析IntentService的源码之前我们需要了解一点东西~

1、handler消息机制

之前总结过,可以看这里:参考

2、HandlerThread

啥是handlerThread呢?其实就是官方封装的一个api方便我们进行"主线程发送消息,子线程处理消息",了解了handler的消息机制后我们可以尝试写下这个demo

(1)主线程发送消息,子线程处理消息demo

class HandlerThreadActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_handler_thread)// open a subThreadthread {Looper.prepare()val handler = Handler{when (it.what) {0x11 ->{Log.d("HandlerThreadActivity","${Thread.currentThread()}收到:${it.obj}")}}return@Handler true}runOnUiThread {Log.d("HandlerThreadActivity","${Thread.currentThread()}UI线程发送一条消息")// ui 线程发送消息handler.sendMessage(Message().apply {what = 0x11obj = "UI线程发送一条消息"})}Looper.loop()}}
}D/HandlerThreadActivity: Thread[main,5,main]UI线程发送一条消息D/HandlerThreadActivity: Thread[Thread-4,5,main]收到:UI线程发送一条消息

观察log发现我们实验成功了,其实不难理解主要是handler与Looper与Thread存在一定的绑定关系。接下来可以看下HandlerThread如何使用的。

(2)HandlerThread使用

    /*** test:HandlerThread usage* */private fun test2() {// 1、创建对象,并开启线程val handlerThread = HandlerThread("HandlerThread")handlerThread.start()// 2、核心,使用两个参数的构造(这里的handleMessage 回调再子线程中的)val handler = Handler(handlerThread.looper) {// 处理消息return@Handler true}// 3、发送消息handler.sendEmptyMessage(0x11)}

借助系统的api就快速了不少,我们可以很方便实现"主线程发送消息,子线程处理消息",接下来看看源码实现。

(3)HandlerThread源码

// 1、首先HandlerThread是一个普通的线程,只是这个线程绑定可Looper(持有Looper成员变成)
public class HandlerThread extends Thread {int mPriority;int mTid = -1;Looper mLooper;// 构造传递的是线程名字public HandlerThread(String name) {super(name);mPriority = Process.THREAD_PRIORITY_DEFAULT;}public HandlerThread(String name, int priority) {super(name);mPriority = priority;}protected void onLooperPrepared() {}// 2、run方法内部进行了实现,核心有两步:// (1) 创建Looper对象// (2) 开启Loop轮训@Overridepublic void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;}// 3、提供了getLooper、getThreadHandler来获取对应的对象public Looper getLooper() {if (!isAlive()) {return null;}boolean wasInterrupted = false;// If the thread has been started, wait until the looper has been created.synchronized (this) {while (isAlive() && mLooper == null) {try {wait();} catch (InterruptedException e) {wasInterrupted = true;}}}if (wasInterrupted) {Thread.currentThread().interrupt();}return mLooper;}@NonNullpublic Handler getThreadHandler() {if (mHandler == null) {mHandler = new Handler(getLooper());}return mHandler;}}

可以看到实现十分简单,只要明白handler的消息机制这个还是很好明白的。

3、IntentService源码

public abstract class IntentService extends Service {
// 1、定义个Looper类型的成员变量(注意这个Looper绑定的线程为HandlerThread工作线程,这就意味着消息的处理是在工作线程)private volatile Looper mServiceLooper;private volatile ServiceHandler mServiceHandler;private String mName;private boolean mRedelivery;//2、定义个Handler,这个handler的handleMessage回调在工作线程(Looper绑定的为工作线程)private final class ServiceHandler extends Handler {public ServiceHandler(Looper looper) {super(looper);}@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent)msg.obj);stopSelf(msg.arg1);}}public IntentService(String name) {super();mName = name;}public void setIntentRedelivery(boolean enabled) {mRedelivery = enabled;}@Overridepublic void onCreate() {super.onCreate();//3、创建HandlerThread并绑定LooperHandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);}@Overridepublic void onStart(@Nullable Intent intent, int startId) {Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);}@Overridepublic int onStartCommand(@Nullable Intent intent, int flags, int startId) {onStart(intent, startId);return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;}@Overridepublic void onDestroy() {mServiceLooper.quit();}// 这里需要注意 方法默认返回为空。从源码也可看出无bindService@Override@Nullablepublic IBinder onBind(Intent intent) {return null;}protected abstract void onHandleIntent(@Nullable Intent intent);
}

IntentService替代方案

JobIntentService

参考

官方文档

活儿好又不纠缠的IntentService

Android IntentService详解(源码分析)

相关内容

热门资讯

SpringBoot的单例模式... 目录 Spring使用的设计模式 单例模式简介 Spring所管理的注解 Spring获取对象时加...
小米总裁:一个能打SU7的对手... 5月27日,小米集团总裁、小米品牌总经理卢伟冰在小米一季度业绩电话会上表示,“SU7发布这么久,一款...
港股创新药ETF(159567... 5月30日,港股医药股走强,石药集团涨近8%,消息面上,石药集团在港交所公告,集团目前正与若干独立第...
2023年“网络安全”赛项江苏... 2023年中职组江苏省淮安市“网络空间安全”赛项 ①.2023年中职组江苏省淮安市任务书②.2023...
ArcGIS: 如何利用模型构... 01 实验数据说明chengdu.pix(栅格图像),其中...
从对标星巴克到沦为 “小透明”... 来源 | 伯虎财经(bohuFN)作者 | 林恩凭借“茶饮+烘焙”的双品类模式与对空间体验的执着追求...
图形视图框架QGraphics... QGraphicsScene 该类充当 QGraphicsItems 的容器。它与 QGraphic...
A股三大指数低开 CPO概念跌...   中新经纬5月30日电 30日早间,A股三大指数集体低开,上证指数跌0.14%,报3358.81点...
广东虎门通报小车高架坠桥5人死... 近日,广东东莞环莞快速路虎门段的一起交通事故引发了广泛关注。5月19日,有网友反映其侄儿驾车经过该路...
全球资产再平衡,港股创新药赛道... 近年来,全球资本市场的结构性调整愈发显著。在美联储加息周期临近尾声、地缘博弈常态化背景下,资金正重新...
警惕信创ETF高溢价风险 摘要: 海光信息和中科曙光计划进行资产重组,持有这两只股票权重较高的信创ETF(159537)受到市...
Spring Boot/Clo... 一、前言 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 Sentinel ...
新思科技:在中国市场销售芯片设... 当地时间5月29日,新思科技称已收到美国商务部工业和安全局 (BIS) 信函,告知新思科技与中国相关...
TIME_WAIT 尽可能客户... 、LISTENING状态   FTP服务启动后首先处于侦听(LISTENING...
蓝桥杯 - 皮亚诺曲线距离 题目描述 皮亚诺曲线是一条平面内的曲线。 下图给出了皮亚诺曲线的 111 阶情形,它是...
卖枕头,真能救酒店? 酒店卖枕... 定焦One(dingjiaoone)原创见习作者 | 何欣欣编辑 | 金玙璠在行业整体规模狂飙突进的...
手写-签名的隐私政策 本应用尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本...
给车机投放广告?深蓝汽车CEO... 文 / 零度来源 / 节点财经5月27日晚间,深蓝汽车在其官方微博账号发文称,“今日,我们关注到部分...
ElasticSearch-第... 目录 ElasticSearch简介 ElasticSearch 应用场景 ElasticSearc...
JAVA练习82-在排序数组中... 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮...
最大值最小值归一化_sklea...  然后我们再来看一下,再来说一下归一化 比如:在公司有两个人,一个是W2 他能力强,然后领导给他分配...
中金公司:微盘风格未来可能仍有... 中金公司研报称,展望未来,微盘风格可能呈现优势边际弱化、仍存在一定结构性机会的格局。政策端对科创小微...
【超详细】MMLab分类任务m... 本文详细介绍了使用MMLab的mmclassification进行分类任务的环境配置、训练与预测流程...
内地优质科技企业“排大队”赴港... 科技企业纷纷涌向港股市场。Wind资讯数据显示,截至5月29日,有5家企业聆讯通过,另有155家企业...
Spring学习(三) Spring的AOP的XML开发(重要指数五颗星*****) 一、AOP...
原创 今... 在1998年房改后,我国房地产市场经历了一次爆发式增长,许多购房者借此机会实现了财富的快速增值,尤其...
原创 A... 5月30日,新股打新市场迎来影石创新的发行申购。它在网上发行656万股,顶格申购需配沪市股票市值6....
15个新一线城市名单出炉,郑州... 【大河财立方 记者 程帅星】5月28日,第一财经旗下新一线城市研究所发布《2025新一线城市魅力排行...
Vector底层源码解析 Java源码系列:下方连接 http://t.csdn.cn/Nwzed 文章目录...
月内3家券商定增迎来新进展,加... 前,证券行业的竞争愈发激烈,资本实力成为券商在市场竞争中制胜的关键因素。近期,证券行业再融资事项迎来...