JobPlus知识库 互联网 其它 文章
Android HandlerThread使用总结

简介

首先我们看到HandlerThread很快就会联想到Handler。Android中Handler的使用,一般都在UI主线程中执行,因此在Handler接收消息后,处理消息时,不能做一些很耗时的操作,否则将出现ANR错误。

Android中专门提供了HandlerThread类,来解决该类问题。HandlerThread类是一个线程专门处理Hanlder的消息,依次从Handler的队列中获取信息,逐个进行处理,保证安全,不会出现混乱引发的异常。HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量。

在看看官方的对他的讲解

Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.

大致意思就是说HandlerThread可以创建一个带有looper的线程。looper对象可以用于创建Handler类来进行来进行调度。接下来看看HandlerThread的源码

package android.os;public class HandlerThread extends Thread {    int mPriority;    int mTid = -1;    Looper mLooper;    public HandlerThread(String name) {        super(name);        mPriority = Process.THREAD_PRIORITY_DEFAULT;    }    protected void onLooperPrepared() {    }    @Override    public void run() {        mTid = Process.myTid();        Looper.prepare();        synchronized (this) {            mLooper = Looper.myLooper();            notifyAll();        }        Process.setThreadPriority(mPriority);        onLooperPrepared();        Looper.loop();        mTid = -1;    }

线程run()方法当中先调用Looper.prepare()初始化Looper,最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环).prepare()呢。

Handler原理

要理解Handler的原理,理解如下几个概念即可茅塞顿开。

  • Message 意为消息,发送到Handler进行处理的对象,携带描述信息和任意数据。
  • MessageQueue 意为消息队列,Message的集合。
  • Looper 有着一个很难听的中文名字,消息泵,用来从MessageQueue中抽取Message,发送给Handler进行处理。
  • Handler 处理Looper抽取出来的Message。

用法

HandlerThread thread = newHandlerThread("handler_thread");thread.start();//必须要调用start方法final Handlerhandler = newHandler(thread.getLooper()){

其他api

//用于返回与该线程相关联的Looper对象thread.getLooper();//获得该线程的Idthread.getThreadId();//结束当前的Looper 循环。thread.quit();//用于looper取出的消息处理thread.run();

实例

当我点击按钮之后,两个蓝色的方块变成了图片。在按钮点击事件中我添加了两个下载图片的任务(模拟情况下),并在加载完后替换控件的默认图片。很明显很可以看到是有先后顺序的。在第一张图片加载完后第二张图片才会显示。

MainActivity public class MainActivity extends AppCompatActivity {    private HandlerThread handlerThread;    private ImageView imageView,imageView1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();    }    private void init() {        imageView= (ImageView) findViewById(R.id.imageView);        imageView1= (ImageView) findViewById(R.id.imageView1);        handlerThread = new HandlerThread("MainActivity");        handlerThread.start();        final Handler handler = new Handler(handlerThread.getLooper());        //点击download开始进行下载        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                handler.post(new MyRunable(1));                handler.post(new MyRunable(2));            }        });    }    class MyRunable implements Runnable {        int pos;        public MyRunable(int pos) {            this.pos = pos;        }        @Override        public void run() {            //模拟耗时            try {                Thread.sleep(2000);            } catch (InterruptedException e) {                e.printStackTrace();            }            if (pos == 1) {                imageView.post(new Runnable() {                    @Override                    public void run() {                        imageView.setBackgroundResource(R.mipmap.ic_launcher);                    }                });            } else {                imageView.post(new Runnable() {                    @Override                    public void run() {                        imageView1.setBackgroundResource(R.mipmap.ic_launcher);                    }                });            }        }    }    @Override    protected void onDestroy() {        super.onDestroy();        handlerThread.quit();//停止Looper的循环    }}

总结

HandlerThread适合在只需要在一个工作线程(非UI线程)+任务的等待队列的形式,优点是不会有堵塞,减少了对性能的消耗,缺点是不能同时进行多任务的处理,需要等待进行处理。处理效率较低。


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
432人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序