专栏首页AnRFDevAndroid IntentService 分析和用法

Android IntentService 分析和用法

IntentService的分析和用法,实用性介绍。

IntentService 简介

  • IntentService继承自Service,可用startService启动,也需要在AndroidManifest.xml中注册
  • IntentService在一个单独的worker线程中处理任务
  • 任务完成后,会自动停止
  • 可多次启动同一个IntentService,它们会自一个接一个地排队处理

IntentService 与 Service

耗时任务可以不用在Service中手动开启线程。 当操作完成时,我们不用手动停止IntentService,它会自动判定停止。

IntentService 自动停止

参考IntentService源码:

private volatile ServiceHandler mServiceHandler;

private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        onHandleIntent((Intent)msg.obj);
        stopSelf(msg.arg1); // 传入startID
    }
}

@Override
public void onCreate() {
    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

@Override
public void onStart(@Nullable Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId; // 这个是停止服务的依据
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}

利用ServiceHandler来控制生命周期。onCreate方法中开启了一个HandlerThread来处理请求。

onStart中获取到startId。在ServiceHandler中每次处理完一个命令都会调用stopSelf(int startId)方法来停止服务。

IntentService直到命令队列中的所有命令被执行完后才会停止服务。

用法示例

新建一个模拟计算的后台服务CalIntentService继承IntentService

/**
 * 模拟计算的后台服务
 * Created by Rust on 2017/6/9.
 */
public class CalIntentService extends IntentService {

    private static final String TAG = "rustApp";
    private int mStartId = 0;

    /**
     * 一定要一个无参构造器
     */
    public CalIntentService() {
        this("cal_intent_service_name");
    }

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public CalIntentService(String name) {
        super(name);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        super.onStart(intent, startId);
        mStartId = startId;
        Log.d(TAG, "[CalIntentService] onStart, startId=" + mStartId); // 复写这个方法来看startId
    }

    @Override
    public void onDestroy() {
        super.onDestroy(); // 观察生命周期
        Log.d(TAG, "[CalIntentService] onDestroy. StartId=" + mStartId);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        if (null != intent) {
            String name = intent.getStringExtra("name");
            String msg = intent.getStringExtra("msg");
            Log.d(TAG, "[CalIntentService] 收到 name:" + name + ", msg:" + msg + ", at "
                    + Thread.currentThread().toString());
        }
        try {
            Thread.sleep(1000); // 模拟耗时操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.d(TAG, "[CalIntentService] 计算结束.  mStartId=" + mStartId);
    }
}

AndroidManifest中注册这个服务。目前只允许本App使用

<service
    android:name="com.rustfisher.service.CalIntentService"
    android:exported="false" />

Activity中启动这个服务

btn2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent calIntent = new Intent(getApplicationContext(), CalIntentService.class);
        calIntent.putExtra("name", "Rust");
        calIntent.putExtra("msg", "Click event: " + mClickCount++);
        startService(calIntent);
    }
});

在手机上运行,快速点击几次按钮,启动IntentService,logcat输出

[CalIntentService] onStart, startId=1
[CalIntentService] 收到 name:Rust, msg:Click event: 0, at Thread[IntentService[cal_intent_service_name],5,main]
[CalIntentService] onStart, startId=2
[CalIntentService] onStart, startId=3
[CalIntentService] onStart, startId=4
[CalIntentService] 计算结束.  最新StartId=4
[CalIntentService] 收到 name:Rust, msg:Click event: 1, at Thread[IntentService[cal_intent_service_name],5,main]
[CalIntentService] 计算结束.  最新StartId=4
[CalIntentService] 收到 name:Rust, msg:Click event: 2, at Thread[IntentService[cal_intent_service_name],5,main]
[CalIntentService] 计算结束.  最新StartId=4
[CalIntentService] 收到 name:Rust, msg:Click event: 3, at Thread[IntentService[cal_intent_service_name],5,main]
[CalIntentService] 计算结束.  最新StartId=4
[CalIntentService] onDestroy. StartId=4

可以看出,先执行onStart,然后排队执行onHandleIntent。任务全部结束后自行停止。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android多线程:IntentService用法&源码分析

    IntentService是Android里面的一个封装类,继承自四大组件之一的Service。

    Carson.Ho
  • Android查缺补漏(线程篇)-- IntentService的源码浅析

    codingblock
  • Android查缺补漏(线程篇)-- IntentService的源码浅析

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8975114.html

    codingblock
  • Android查缺补漏(线程篇)-- IntentService的源码浅析

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8975114.html

    codingblock
  • Android 进阶16:IntentService 使用及源码解析

    It’s time to start living the life you’ve only imagined. 在前面两篇文章 源码解读 Android 消息...

    张拭心 shixinzhang
  • andriod如何搭建自己的轮询框架

    很多时候Android应用需要每间隔一段时间向服务器请求数据,如果服务器数据有更新则通知界面变化。Android中最常用的红点一般采用的就是轮询,红点是为了在数...

    砸漏
  • Android:请收好这份全面&详细的多线程学习指南!

    具体请看文章:Android Handler:这是一份 全面、详细的Handler机制 学习攻略

    Carson.Ho
  • 创建后台任务的两种代码模式

    用户1907613
  • 金九银十准备换场地?对标腾讯T3的Android高级工程师面试大纲及时雨来了

    1、Activity是什么 2、Activity四种状态 3、Activity生命周期 4、进程的优先级 5、Activity任务栈 6、Activity启动模...

    Android技术干货分享
  • IntentService使用及源码分析

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/...

    程序员徐公
  • 仿淘宝收货地址,本地数据库

    谁说咱们攻城狮不能写出既幽默又能懂的博客呢,本人想推出一系列博文,可以给刚接触Android开发的做一个参考,也可以与接触Android已久的各路大神比较一下,...

    xiangzhihong
  • IntentService解析

    Step1. 定义IntentService的子类:传入线程名称、重写 onHandleIntent()方法

    用户1205080
  • Android 多线程实现方式

    通常来说,一个应用至少有一个进程,而一个进程至少有一个线程。 线程是 CPU 调度的基本单位,进程是系统资源分配的基本单位。

    字节流动
  • Android四大组件:Service史上最全面解析

    接下来,我将介绍每种Service的具体使用,具体请看我写的文章:Android:(本地、可通信的、前台、远程)Service使用全面介绍

    Carson.Ho
  • Android性能优化(十一)之正确的异步姿势

    在前面的性能优化系列文章中,我曾多次说过:异步不是灵丹妙药,不正确的异步方式不仅不能较好的完成异步任务,反而会加剧卡顿。Android开发中我们使用异步来进行耗...

    用户2898788
  • 浅谈Android 的线程和线程池的使用

    从用途上分,线程分为主线程和子线程;主线程主要处理和界面相关的事情,子线程则往往用于耗时操作。

    砸漏
  • Art of Android Development Reading Notes 11

    《Android开发艺术探索》读书笔记 (11) 第11章 Android的线程和线程池

    宅男潇涧
  • Android多线程介绍

    首先介绍Android中创建线程最基本的两种方法,用到了Thread类和Runnable接口,直接上代码

    码上积木
  • 备战秋招 面试真题: 给你一个Demo 你如何快速定位ANR?

    在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作“应用程序无响应”(ANR:Application Not...

    Android技术干货分享

扫码关注云+社区

领取腾讯云代金券