美文网首页
Android之intentService探索

Android之intentService探索

作者: 放码过来吧 | 来源:发表于2018-03-15 16:09 被阅读133次

    习惯性的带着问题去研究事物的本质,问题提出:
    1. intentService是什么?
    2. intentService既然是服务?跟普通的service有什么区别?
    3. 既然有service,为什么还会出现intentService,有什么优势呢?
    4. intentService的使用场景。

    分析与解决问题
    intentService是什么,我们来看看官方的解释:


    intentService官方介绍.png

    官网的意思就是:intentService 的基类是service,并按照要求处理异步请求(intent的方式发送,其实后面处理的就是intent),客户端通过 startService(intent)发送请求,服务就会按照需要启动,在子线程里面处理每一个intent,当全部intent处理完后就自杀。(差点过了4级,翻译的不好,有更好的翻译可以告诉我)


    1.jpg

    很好,从这里,我们知道intentService本质上也是一个service,intentService继承于service,同时也可以得知,intentService是普通service的一种扩展,我们来看看它的扩展,放码过来吧~

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

    我们来看看onCreate()方法:
    首先创建了一个HandlerThread(只是一个封装了一些东西的子线程,本文不深究,下篇在搞它),接着,用它的looper构造了一个handler对象mServiceHandler,由此我们可以得知,mServiceHandler发送的消息都会在HandlerThread中处理。看到handler,就应该有队列的概念,之前官网解释的处理每一个intent,就是根据先进先出原则依次处理的。
    既然intentService是一个服务,多次启动,也是只会创建一次(onCreate()会调用一次),但是onStartCommand(),每次启动都会调用一次,我们来看看onStartCommand()里面究竟有什么:

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

    好吧,里面调用了onStart()方法,每次启动服务,onStart()每次也会调用咯,我们再去看看onStart():

        @Override
        public void onStart(@Nullable Intent intent, int startId) {
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            mServiceHandler.sendMessage(msg);
        }
    

    这里面,intentService发送了一个消息,这个消息,会在HandlerThread里面处理(因为looper是HandlerThread这个线程的),既然是子线程,那就可以做耗时的一些操作了。接下来,我们来看看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);
          }
      }
    

    很对,就是这里,把发过来的消息给了onHandleIntent()去处理,处理完了直接stopSelf(msg.arg1),这里没有用stopSelf()而是用stopSelf(int startId)来停止服务,是因为stopSelf()会立即停止服务,这个时候可能还有其他消息未处理,stopSelf(int startId)则会当所有消息处理完才会停止服务。回过头,我们再看看onHandleIntent():

        @WorkerThread
        protected abstract void onHandleIntent(@Nullable Intent intent);
    

    是一个抽象方法,别忘了intentService也是一个抽象类,我们要用intentService,就必须实现onHandleIntent()这个方法,这里面就是具体处理一些耗时的操作,比如下载之类的,需要开发者去实现这个方法。

    突然发现,intentService好简单,就是在service的基础上封装了一个handler和一个子线程HandlerThread。在方便我们使用的同时,它最主要的特点也显示出来了,使用队列去处理客户端发送的一个个请求。(说人话:就是多个耗时任务会按顺序依次执行)

    现在回头看我们提出的问题,其实都已经解答了,跟service的区别就是,intentService是它的加强版,实现了按顺序依次执行需求的功能,起到了管理的作用,service却不能做到,这就是优势。适合那些按顺序下载的需求场景。

    下面是一个模拟下载功能demo示例:
    添加多个模拟下载功能,依次按顺序去处理,这是项目的展示图:


    intentService.gif

    这个是github地址: IntentServiceDemo

    相关文章

      网友评论

          本文标题:Android之intentService探索

          本文链接:https://www.haomeiwen.com/subject/pancqftx.html