IntentService源码解析

作者 : 开心源码 本文共2720个字,预计阅读时间需要7分钟 发布时间: 2022-05-12 共231人阅读

假如此时你对Service有些模糊可先简单浏览一下Andriod中各种服务

首先看一下Google给的详情

官方详情
主要的内容就是:IntentService继承Service。异步解决请求,可以自己关闭自己。所有的任务由同一个线程完成。并且是串行执行的。

作为服务,所以其优先级比一般的线程要高。IntentService封装了HandleThreadhandler

HandleThread

HandleThread继承Thread,其实就是个线程。不同的是HandleThread创立了自己的looper。这意味着主线程可以给HandleThread发送消息,让其解决少量耗时操作。

public class HandlerThread extends Thread {            // handlerThread 继承自Thread类    int mPriority;    int mTid = -1;    Looper mLooper;    private @Nullable Handler mHandler;     public HandlerThread(String name) {        super(name);        mPriority = Process.THREAD_PRIORITY_DEFAULT;    }    @Override    public void run() {            // 覆写了Thread类的run方法        mTid = Process.myTid();        Looper.prepare();            // 获取一个Looper        synchronized (this) {            mLooper = Looper.myLooper();            notifyAll();        }        Process.setThreadPriority(mPriority);        onLooperPrepared();        Looper.loop();                // 开启消息循环        mTid = -1;    }}

从源码可以看见HandleThread调用了looper.loop(),这是个无线循环来解决随时可能收到的消息。所以当我们退出的时候应该调用 HandleThread.quit()或者者HandleThread.stopSefely()来终止线程的执行。

onCreate

源码

public void onCreate(){  super.onCreate();  HandleThread thread = new HandleThread("IntentService[" + mName + " ] "); // HandleThread 继承于Thread,前面说过  thread.start();    mServiceLooper = thread.getLooper(); // 获取HandleThread中的消息队列  mServiceHandler = new ServiceHandler(mServiceLooper); // 用这个消息队列初始化一个邮递员Handler}

执行onCreate,初始化HandleThreadHandler对象。让Handler能给HandleThread线程发送消息。

onStartCommand

按照服务的执行生命周期,执行完onCreate初始化之后。每次启动IntentService就会执行一次onStartCommand,这个方法解决每次外界发送的IntentonStartCommand调用了onStart

public void onStart(Intent intent, int startId){  Message msg = mServiceHandler.obtainMessage(); // 从消息池中拿来msg,不用去new,效率更高  msg.arg1 = strartId;  msg.obj = intent; // 用于传递信息  mServiceHandler.sendMessage(msg);}

这里还使用了ServiceHandler,它是 IntentService的内部类,继承于Handler,源码如下

private final class ServiceHandler extends Handler{    public ServiceHandler(Looper looper){      super(looper);    }    @override    public void handleMessage(Message msg){      onHandleIntent((Intent) msg.obj);// 调用IntentService解决消息      stopSelf(msg.arg1);// 等待任务完成之后,中止服务    }}

从上面的源码可以得知, ServiceHandler拥有子线程的looper。它可以向子线程中发送消息,子线程收到消息之后调用Handler.handleMessage()方法解决消息。所以最终消息的解决是在子线程中完成的!!!
需要注意的是,IntentService的内部实现是LooperLooper是顺序解决事件的,所以IntentService也是顺序解决任务的。
验证一下

public class MyIntentService extends IntentService {    private static final String name = "MyIntentService";    public MyIntentService(){        super(name);    }    @Override    protected void onHandleIntent(@Nullable Intent intent) {        // 解决耗时操作,已近开起来新的线程        long id = Thread.currentThread().getId();        try{            Thread.sleep(3000);        }catch (Exception e){            e.printStackTrace();        }        Log.d("Service", "当前线程"+id);    }    @Override    public void onDestroy() {        super.onDestroy();        Log.d("Service","destroy");    }}
// 开启三个任务startService(new Intent(this,MyIntentService.class));startService(new Intent(this,MyIntentService.class));startService(new Intent(this,MyIntentService.class));

验证任务执行的顺序,以及线程号

开启了三个任务给IntentService,可以看见完成的时间恰好差三秒,证实任务执行的顺序是串行的。另外可以看见三个任务也都是在子线程上完成的。Thread id = 1是UI主线程。任务执行完成之后自动调用了destroy

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » IntentService源码解析

发表回复