美文网首页
HandlerThread源码解析

HandlerThread源码解析

作者: HopCoder | 来源:发表于2018-05-03 10:06 被阅读0次

    HandlerThread源码

    它是一个Thread的子类,源码很简单,只有100多行代码
    1、 run()

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare(); //创建了一个Looper对象
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared(); //调用了 onLooperPrepared ,开启Looper.loop前的准备
        Looper.loop(); // 开启了Loop无限循环
        mTid = -1;
    }
    

    可以看到这个方法,run方法创建了一个Looper,在调用了onLooperPrepared()方法后,开启了loop循环。我们需要做的就是重写onLooperPrepared() 做一些初始化工作。
    问题:
    这里开启一个Looper.loop()循环有什么作用呢? 在Handler源码解析中我们可以了解到,loop循环其实就是在Looper对象的MessageQueue对象中无限的取消息,调用Message.target.dispatchMessage方法来处理消息。由此我们可以想到HandlerThread的实际应用,就是通过一个Handler发送消息到这个线程的MessageQueue对象中,然后利用它已经写好的Looper.loop()方法无限循环处理消息。

    HandlerThread应用

    1、HandlerThread的用处
    HandlerThread主要用于处理耗时的多任务操作,比如多任务下载或者多个文件的IO读写
    2、如何使用呢?下面模仿写一个多任务下载的HandlerThread

    public class DownloadThread extends HandlerThread implements Handler.Callback {
    
        private Handler mWorkHandler;
        private Handler mUIHandler;
        private List<String> mDownloadUrlList;
        private final String KEY_URL = "url";
        public static final int TYPE_START = 1;
        public static final int TYPE_FINISHED = 2;
    
        public DownloadThread setDownloadUrlList(List<String> downloadUrlList) {
            mDownloadUrlList = downloadUrlList;
            return this;
        }
    
        public DownloadThread setUIHandler(Handler UIHandler) {
            mUIHandler = UIHandler;
            return this;
        }
    
        public DownloadThread(String name) {
            super(name);
        }
    
        @Override
        protected void onLooperPrepared() {
            super.onLooperPrepared();
    
            mWorkHandler = new Handler(getLooper(), this);
    
            if (mUIHandler == null){
                throw new IllegalArgumentException("Not set UIHandler! ");
            }
    
            if (mDownloadUrlList == null || mDownloadUrlList.size() <= 0){
                throw new IllegalArgumentException("the downloadUrlLsit is null, Please set DownloadUrlList! ");
            }
    
            for (String url : mDownloadUrlList) {
                Message obtain = Message.obtain();
                Bundle bundle = new Bundle();
                bundle.putString(KEY_URL,url);
                obtain.setData(bundle);
                mWorkHandler.sendMessage(obtain);
            }
    
        }
    
        @Override
        public boolean handleMessage(Message msg) {
    
            if (msg == null || msg.getData() == null){
                return false;
            }
            String downloadUrl = msg.getData().getString(KEY_URL);
            Message startMessage = mUIHandler.obtainMessage(TYPE_START);
            mUIHandler.sendMessage(startMessage);
    
            //todo download code
    
            Message finishMessage = mUIHandler.obtainMessage(TYPE_FINISHED);
            mUIHandler.sendMessage(finishMessage);
            return false;
        }
    
        @Override
        public boolean quitSafely() {
            mUIHandler = null;
            return super.quitSafely();
        }
    }
    

    这里模仿写了一个多任务下载的HandlerThread,这是我能想到的最好的应用场景。如果你有比较好的应用场景,请告诉我 谢谢。

    相关文章

      网友评论

          本文标题:HandlerThread源码解析

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