HandlerThread以及IntentService的深入理解

HandlerThread以及IntentService的深入理解

一、HandlerThread

顾名思义:HandlerThread就是可以使用Handler的Thread
所在路径:frameworks/base/core/java/android/os/HandlerThread.java
其run方法如下:

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

其特殊之处在于:普通Thread在run方法中执行耗时任务,而HandlerThread在内部创建消息队列,
外界需要通过Handler发送消息的方式,通知HandlerThread执行具体的任务。

二、IntentService

IntentService是一种特殊的Service,可用于执行后台耗时任务。任务执行完它会自动停止,因为其是服务的原因,其优先级是要远高于其他线程。因为它适合执行高优先级的后台任务。
IntentService里面封装了HandlerThread和Handler,从它的onCreate方法中可以得知。

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

利用HandlerThread的Looper来构建构建Handler,可得知Handler发送的消息最终会到HandlerThread执行。
每次启动IntentService,它的onStartCommand都会被调用一次,它会在这个方法里面处理外界发送过来的Intent,因为onStartCommand里面调用了onStart()函数,所以接下来看看onStart方法的实现:


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

可以得知,在这个方法里面,只是通过ServiceHandler发送了一条信息。
接下来看看ServiceHandler的实现:

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

在这个函数中可以看到,ServiceHandler会对这个消息进行处理,其中这个Intent对象和外界的startService(intent)中的intent内容是完全一致,然后使用stopSelf(int startId)这个函数来停止服务(这个函数会等待所有的消息处理完毕后才终止服务),如果直接使用stopSelf()会立刻停止服务。
IntentService内部则通过消息的方式向HandlerThread请求执行任务,Handler中的Looper是顺序处理消息的,这就意味着IntentService也是顺序执行后台任务的,当有多个后台任务同时存在时,这些后台任务会按照外界发起的顺序排队执行。
这里附上IntentService的一个小实例:

    public class IntentServiceA extends IntentService {
        private static final String TAG = "LocalIntentService";
        public LocalIntentService() {
            super(TAG);
        }
        @Override
        protected void onHandleIntent(Intent intent) {
            String action = intent.getStringExtra("task_action");
            Log.d(TAG,"receive task :" + action);
            if ("com.ryg.action.TASK1".equals(action)) {
                Log.d(TAG,"handle task: " + action);
            }
        }
        @Override
        public void onDestroy() {
            Log.d(TAG,"service destroyed.");
            super.onDestroy();
        }
    }

在onHandleIntent方法中会从参数中解析出后台任务的标识,即task_action字段所代表的内容,然后根据不同的任务标识来执行具体的后台任务。

参考《Android开发艺术探索》

发布了14 篇原创文章 · 获赞 45 · 访问量 2450

猜你喜欢

转载自blog.csdn.net/weixin_42683077/article/details/100006748