Android IntentService 源码解析

作者: 没有颜色的菜 | 来源:发表于2018-09-06 23:04 被阅读1次

    前言

    顾名思义,是一个 Service,先说和普通的 Service 的区别吧,普通的 Service 通常运行在主线程,而 IntentService 的处理逻辑在子线程里,另外 Service 需要自己去 destroy,而 IntentService 在处理完自己的逻辑时会自动结束,那他是怎么实现线程切换,主要还是 Handler 机制,内部有一个 HandleThread,关于这个,可以查看 [HandlerThread 源码解析] (https://www.jianshu.com/p/5ff83236c8e2)

    前世今生

    public abstract class IntentService extends Service {}
    

    继承自 Service,拥有 Service 的特性,不熟悉 Service 的同学可以自行百度,面试必问的,然而感觉我还是不想深入了解,以后再说吧
    记住

    onCreate -> onStartCommand -> onDestroy
    onCreate -> onBind -> onUnbind
    

    自己写一个 IntentService

    public class MyIntentService extends IntentService {}
    

    源码解析

    很熟悉的 Looper 和 ServiceHandler

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

    看一下 onCreate,初始化了一个 HandlerThread,然后再把他的 Looper 拿出来,然后抛弃了它,这个 Looper 是子线程的 Looper,因此事件处理也发生在子线程。利用这个 Looper 新建了一个 Handler

      @Override
        public void onCreate() {
            // TODO: It would be nice to have an option to hold a partial wakelock
            // during processing, and to have a static startService(Context, Intent)
            // method that would launch the service & hand off a wakelock.
    
            super.onCreate();
            HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
            thread.start();
    
            mServiceLooper = thread.getLooper();
            mServiceHandler = new ServiceHandler(mServiceLooper);
        }
    

    启动以后调用 onStart,发送一个消息,onHandleIntent((Intent)msg.obj) 里面进行处理,我们要重写这个方法,通常这个在子线程中运行

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

    处理完即关闭,不需要手动关闭

        public final void stopSelf() {
            stopSelf(-1);
        }
    
        /**
         * Old version of {@link #stopSelfResult} that doesn't return a result.
         *  
         * @see #stopSelfResult
         */
        public final void stopSelf(int startId) {
            if (mActivityManager == null) {
                return;
            }
            try {
                mActivityManager.stopServiceToken(
                        new ComponentName(this, mClassName), mToken, startId);
            } catch (RemoteException ex) {
            }
        }
    

    在我们自己的 IntentService 里面,写处理的逻辑,由于是在子线程中,所以可以处理耗时的逻辑,不必担心 ANR,普通 Service 由于在主线程运行,所以不能直接处理耗时逻辑

        @Override
        protected void onHandleIntent(Intent intent) {
            if (intent != null) {
                final String action = intent.getAction();
                if (ACTION_FOO.equals(action)) {
                    final String param1 = intent.getStringExtra(EXTRA_PARAM1);
                    final String param2 = intenonHt.getStringExtra(EXTRA_PARAM2);
                    handleActionFoo(param1, param2);
                } else if (ACTION_BAZ.equals(action)) {
                    final String param1 = intent.getStringExtra(EXTRA_PARAM1);
                    final String param2 = intent.getStringExtra(EXTRA_PARAM2);
                    handleActionBaz(param1, param2);
                }
            }
        }
    

    小结

    非常简单的 IntentService,使用的时候注意与普通 Service 的区别即可,里面使用了 HandlerThread 获取 Looper 对象,处理完会自动关闭,即调用 onDestroy,再次启动又重新走 Service 的生命周期,一个问题,如果多次 startService,那么 onHandleIntent 是怎么样的呢?答案是一次执行,因为 Looper 事件处理是阻塞的

    相关文章

      网友评论

        本文标题:Android IntentService 源码解析

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