多线程编程之HandlerThread

在前面2篇内容中针对Java中的多线程已经做了详细的介绍,本篇将针对在Android中多线程这块Google已经为我们封装好了的API的介绍和使用
多线程编程基础之 wait()、notify()、sleep()、join()、yield()、synchronized关键字Lock锁等
多线程编程之 Runnable、Callable、Future、FutureTask和AsyncTask源码分析

HandlerThread

HandlerThread本质上是一个线程类,继承自Thread类,但是HandlerThread有自己的Looper对象,可以进行looper循环,不断从MessageQueue中取消息,可以处理多个任务,从而达到开启一个线程起到多个线程的作用。

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();
    HandlerThread fetchThread = new HandlerThread("fetching_thread");
    Handler fetchHandler;
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv);
        //启动线程
        fetchThread.start();
        //通过fetchHandler发送的消息,会被fetchThread线程创建的轮询器拉取到
        fetchHandler = new Handler(fetchThread.getLooper()){
            @Override
            public void handleMessage(Message msg) {
                //模拟访问网络延迟
                SystemClock.sleep(1000);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        double value = new Random().nextDouble() * 10;
                        String price = xiaoshuToString(value);
                        tv.setText("美元汇率:"+price);
                        Log.e(TAG, "美元汇率:"+price);
                    }
                });
                //循环执行
                fetchHandler.sendEmptyMessage(1);
            }
        };

    }
    public static String xiaoshuToString(double f) {
        DecimalFormat df = new DecimalFormat("0.0");//格式化小数
        String priceF = df.format(f);//返回的是String类型
        return priceF;
    }
@Override
    protected void onResume() {
        super.onResume();
        fetchHandler.sendEmptyMessage(1);
    }
    @Override
    protected void onStop() {
        super.onStop();
        fetchThread.quit(); //取消
    }
MainActivity: 美元汇率:4.6
MainActivity: 美元汇率:3.6
MainActivity: 美元汇率:7.3
MainActivity: 美元汇率:6.3
MainActivity: 美元汇率:9.0
MainActivity: 美元汇率:8.0

上面案例模拟了需要不断的从网络获取数据,下面重源码的角度局分析HandlerThread工作机制

  • 创建HandlerThread

    HandlerThread fetchThread = new HandlerThread("fetching_thread");

多线程编程之HandlerThread_第1张图片
HT01

上图可以看到HandlerThread继承了Thread 并且在初始化的时候 赋值了线程名称和线程优先级(默认为0) 当然可以还自定义线程优先级 new HandlerThread(String name, int priority)

  • 启动HandlerThread线程

    fetchThread.start();//启动线程

多线程编程之HandlerThread_第2张图片
TH02

在Thread中调用start()方法就会将run()方法在分线程中去调用执行 HandlerThread在调用start()方法时 在run()方法中创建了Looper对象 并且开启的Looper轮询器Looper.loop()不断的将消息取出 交由发送消息的Handler去处理消息 而这些操作都是在分线程run()方法中执行的(如果有对Handler消息机制不了解的 可以去看看 Handler消息机制)

  • 获取HandlerThread中的Looper对象创建Handler

    HandlerThread fetchThread = new HandlerThread("fetching_thread");
    Handler fetchHandler;
    fetchHandler = new Handler(fetchThread.getLooper());

多线程编程之HandlerThread_第3张图片
TH03

上图是通过 new Handler(Looper looper)创建的Handler对象 其作用是需要获取该Looper对象下的MessageQueue对象 这样Handler发送消息的时候 将该消息插入到MessageQueue队列中 Looper就能够从该队列中不断的取消息 再交由Handler处理 如下图:
多线程编程之HandlerThread_第4张图片
TH05

  • 清空消息
HandlerThread fetchThread = new HandlerThread("fetching_thread");
@Override
    protected void onStop() {
        super.onStop();
        fetchThread.quit(); 
    }

多线程编程之HandlerThread_第5张图片
TH06

关于MessageQueue是怎么清空消息的 需要自行对照源码去分析 这里就不多做介绍
最后:
关于HandlerThread和Handler的结合使用就介绍完了 其核心就是在HandlerThread的run()执行了 Looper对象的创建 以及开启Looper.loop()轮询器 在HandlerThread调用start()方法时 run()方法就会在分线程中执行 就导致了Handler在handleMessage(Message msg)处理消息的时候在分线程中执行。

你可能感兴趣的:(多线程编程之HandlerThread)