IntentService解析

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: IntentService是一个专门用来处理异步线程的一个服务,它内部创建了一个消息队列以及一个Handler对象,其它组件将Intent发送过来之后,IntentService会将这个Intent通过消息队列发送到工作线程,所以,我们可以放心大胆的在IntentService内部做耗时操作,而不必单独开启线程。

IntentService是一个专门用来处理异步线程的一个服务,它内部创建了一个消息队列以及一个Handler对象,其它组件将Intent发送过来之后,IntentService会将这个Intent通过消息队列发送到工作线程,所以,我们可以放心大胆的在IntentService内部做耗时操作,而不必单独开启线程。

好,大概描述了下,我们看一下它的实现方式:

package android.app;

import android.annotation.WorkerThread;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;

...
public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

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

	...
    public IntentService(String name) {
        super();
        mName = name;
    }

	...
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @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(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

	...
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

	...
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

	...
    @WorkerThread
    protected abstract void onHandleIntent(Intent intent);
}

将注释代码删除掉之后,真正的实现代码很少,现在将对这些代码一一说明,首先是onCreate方法:

onCreate方法主要做了以下事情:

创建HandlerThread线程并启动,使用HandlerThread对象所创建的Looper对象初始化ServiceHandler对象,这样,就可以通过ServiceHandler对象HandlerThread中的消息队列发送数据了,我们看看他们之间是如何实现的,首先是HandlerThread:

...
package android.os;

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

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }
    
    ...
    public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }
        
        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }

    ...
    public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
    }

    ...
    public boolean quitSafely() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quitSafely();
            return true;
        }
        return false;
    }

    ...
    public int getThreadId() {
        return mTid;
    }
}

这个中的代码也不多,我们看主要的run方法:

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

run方法主要做了以下事情:

调用Looper.prepare();在当前线程中初始化一个Looper消息循环对象,并初始化了一个消息队列,拿到这个线程的Looper对象,然后开启消息循环访问模式。

接着回到IntentService的onCreate方法中,使用刚才的工作线程中的Looper对象来初始化ServiceHandler,使mServiceHandler对象向这个线程的Looper中发送消息。


准备工作做好之后,接下来的逻辑就简单了,其它组件通过startService方法,将Intent传递到这个服务中,会调用onStartCommand方法,onStartCommand调用onStart方法,而onStart方法会将接收到的Intent对象作为被传送的消息实体通过ServiceHandler发送到工作线程,然后我们如果使用的话,直接重写onHandleIntent就可以,onHandleIntent收到对象的时候已经处在工作线程当中。

我们在onHandleIntent方法中处理完毕任务之后,不必手动去调用stopSelf去停止服务,IntentService已经帮我们做了这样的处理。说到这里,可能你会有疑问,如果我在很短的时间内发送了多个请求,那么第一个请求处理完毕那服务不就终止了吗,后面的怎么处理呢,对于这个问题,需要详细了解一下stopSelf的说明:

如果我们现在工作在默认模式,同一时间只有一个Intent会被处理,如果在当前这个任务处理结束之前还有一个Intent请求过来的话,那它就不会被终止,它的原因与stopSelf有关系,stopSelf会判断终止的startId是否是最后发送过来的startId,所以,疑问解决了。


到这里基本的解释就说完了,有疑问欢迎留言。

目录
相关文章
|
算法 调度
详解操作系统的调度
详解操作系统的调度
799 0
|
算法 Shell 计算机视觉
【特效】对实时动态人脸进行马赛克及贴图马赛克处理及一些拓展
【特效】对实时动态人脸进行马赛克及贴图马赛克处理及一些拓展
523 0
【moment】moment时间前后一个月,小于当天 或15天内
【moment】moment时间前后一个月,小于当天 或15天内
|
9月前
|
人工智能 运维 云计算
全新无影,来了!
全新无影,来了!
|
Kubernetes Cloud Native 云计算
云原生时代的技术演进:Kubernetes与微服务架构的完美融合
随着云计算技术的飞速发展,云原生概念逐渐深入人心。本文将深入探讨云原生技术的核心——Kubernetes,以及它如何与微服务架构相结合,共同推动现代软件架构的创新与发展。文章不仅剖析了Kubernetes的基本工作原理,还通过实际案例展示了其在微服务部署和管理中的应用,为读者提供了一条清晰的云原生技术应用路径。
283 2
|
缓存 Kubernetes 应用服务中间件
k8s学习--helm的详细解释及安装和常用命令
k8s学习--helm的详细解释及安装和常用命令
464 0
k8s学习--helm的详细解释及安装和常用命令
|
自然语言处理 Java 关系型数据库
Elasticsearch【环境搭建 01】elasticsearch-6.4.3 单机版不能以root用户运行es 及 max_map_count 问题解决(含 安装包+分词插件 云盘资源)
Elasticsearch【环境搭建 01】elasticsearch-6.4.3 单机版不能以root用户运行es 及 max_map_count 问题解决(含 安装包+分词插件 云盘资源)
198 0
|
传感器 监控 物联网
探索物联网传感器与执行器:连接万物的感知与控制
本篇详细介绍了物联网中传感器与执行器的关键概念与应用。我们探讨了传感器的原理与分类,包括温度、湿度、光照、运动传感器等的实际应用。同时,我们还研究了执行器的作用,并通过Python代码示例展示了如何控制LED灯作为执行器。这些知识有助于读者深入了解物联网中感知与控制的基础,为创造智能化应用奠定了基础。
1120 1
|
负载均衡 网络架构 Docker
Traefik
Traefik 是一款开源的反向代理和负载均衡工具,它可以自动地为容器化的应用程序提供动态路由和负载均衡服务。Traefik 支持多种后端服务,并且可以根据容器的标签和元数据自动发现和配置后端服务。
754 1