HandlerThread源码解析

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,这是我能想到的最好的应用场景。如果你有比较好的应用场景,请告诉我 谢谢

猜你喜欢

转载自blog.csdn.net/dingshuhong_/article/details/80175939
今日推荐