美文网首页程序员Android
Android多线程通信总结(二)- IntentService

Android多线程通信总结(二)- IntentService

作者: Android阿南 | 来源:发表于2021-01-12 18:59 被阅读0次

    引言

    相信大家在面试的时候都会被问到这个问题“说说Android中的多线程吧?”,那么对于这个问题我们可以回答的点就比较多了。比如Thread,Runnable,ThreadPoolExecutor,这些都是Java开发或者android开发中常用的线程处理方式,Android中为了保证线程安全,线程通信的效率,开发的便捷性,提供了HandlerThread,IntentService,AsyncTask。那么今天我们就来聊一聊IntentService。

    Service和IntentService的区别与联系

    我们都知道Service是可以在后台处理一些任务所创建的服务,并不是所有的任务都可以在后台进行处理,比如一些耗时的操作,如果我们不开启子线程去处理这些任务,还是会引起卡顿现象。同时,我们需要考虑的点就是ANR,ANR是指应用程序无响应。那么对于Android来说他有不同的情况会产生ANR,具体信息如下:

    1\. 输入事件(按键和触摸事件)5s内没有被处理:Input event dispatching timed out
    2\. BroadcaseReceiver的事件(onReceive方法)在规定时间内没处理完(前台广播10s,后台广播60s):Timeout of broadcast BroadcastRecord
    3\. service前台20s,后台200s没有完成启动 :Timeout executing service
    4\. ContentProvider的publish在10s内没进行完:Timeout publishing content providers
    复制代码
    

    从上面的知识点可以看到,Service中同样会发生ANR。所以在我们开发的过程中如果需要在Service中处理耗时的操作,就可以使用Android提供给我们的IntentService类。

    IntentService是一个抽象类,其中的抽象方法onHandleIntent,由开发者自己去实现。

    protected abstract void onHandleIntent(@Nullable Intent intent);
    复制代码
    

    IntentService会创建单独的worker线程来处理所有的intent请求,因此开发者无须处理多线程的问题,

    IntentService内部持有一个HandlerThread,并通过HandlerThread来实现消息的处理

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

    IntentService会持有一个内部类ServiceHandler

    private final class ServiceHandler extends Handler {
       public ServiceHandler(Looper looper) {
          super(looper);
       }
    
       @Override
       public void handleMessage(Message msg) {
            //通过抽象方法将当前消息的处理方式交给开发者执行
          onHandleIntent((Intent)msg.obj);
          //回调执行完成之后会执行stopSelf来停止当前Service
          stopSelf(msg.arg1);
        }
    }
    复制代码
    

    stopSelf(msg.arg1)方法中的msg.arg1是一个int值,相当于一个请求的唯一标识。每发送一个请求,会生成一个唯一的标识,然后将请求放入队列,当全部执行完成(最后一个请求也就相当于getLastStartId == startId),或者当前发送的标识是最近发出的那一个(getLastStartId == startId),则会销毁我们的Service.

    Service销毁的时候会执行onDestory()方法来停止IntentService内部的Looper循环

    @Override
    public void onDestroy() {
       mServiceLooper.quit();
    }
    复制代码
    

    IntentService的大致工作流程是

    image

    具体的IntentService源码如下,感兴趣的可以多看看,对照上面的流程进行分析

    public abstract class IntentService extends Service {
        private volatile Looper mServiceLooper;
        @UnsupportedAppUsage
        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(@Nullable Intent intent, int startId) {
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            mServiceHandler.sendMessage(msg);
        }
    
        @Override
        public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
            onStart(intent, startId);
            return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
        }
    
        @Override
        public void onDestroy() {
            mServiceLooper.quit();
        }
    
        @Override
        @Nullable
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @WorkerThread
        protected abstract void onHandleIntent(@Nullable Intent intent);
    }
    
    复制代码
    

    总结:其实IntentService的源码就是内部通过HandlerThread+Service来实现的,我个人觉得源码的阅读有利于我们对开发规范,开发思想上的提升,比如IntentService内部的抽象方法的运用,在平时我们的程序开发过程中也可以参考这种方式对代码进行书写。

    作者:Android大师哥
    链接:https://juejin.cn/post/6916543579372388366
    来源:掘金

    相关文章

      网友评论

        本文标题:Android多线程通信总结(二)- IntentService

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