Handler、Looper、HandlerThread关系梳理

2020-06-02  本文已影响0人  捉影T_T900

一、一条核心对应关系:

Thread(1):Looper(1):MessageQueen(1):Handler(n)

(1)Thread:作为一个任务执行的独立环境,内部持有Looper、MessageQueen
(2)Looper:本质是一个轮询器,在Thread内部运行,不断从MessageQueen中取出Message进行分发
(3)MessageQueen:消息队列
(4)Handler:Message的搬运工,将Message推至MessageQueen中

二、HandlerThread的概念和使用

鉴于以上对象过多,关系复杂,使用起来不方便,缩一Google退出了HandlerThread这个类方便更高效地使用Handler功能。

如果没有HandlerThread,但又想实现子线程处理Handler任务分发功能的话,需要这样操作,显得复杂难懂:

new Thread () {
    @Override
    public void run() {
        Looper.prepare();
        Hnadler handler = new Handler();
        Looper.loop();
    } 
}

HandlerThread本质上是一个Thread,做着普通的Thread做的工作。

使用方法:

public class MainActivity extends AppCompatActivity {

    Handler mainHandler, workHandler;
    HandlerThread handlerThread;

    TextView result;
    Button button1;
    Button button2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        result = findViewById(R.id.result);
        button1 = findViewById(R.id.button1);
        button2 = findViewById(R.id.button2);

        // 主线程的handler
        mainHandler = new Handler();

        handlerThread = new HandlerThread("My HandlerThread");
        handlerThread.start();

        // handlerThread的handler
        workHandler = new Handler(handlerThread.getLooper()){
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case 1:
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Log.i("XXX", "workHandler:" + Thread.currentThread().getName());
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                Log.i("XXX", "mainHandler:" + Thread.currentThread().getName());
                                result.setText("第一次执行");
                            }
                        });
                        break;
                    case 2:
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Log.i("XXX", "workHandler:" + Thread.currentThread().getName());
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                Log.i("XXX", "mainHandler:" + Thread.currentThread().getName());
                                result.setText("第二次执行");
                            }
                        });
                        break;
                }
            }
        };

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                workHandler.sendEmptyMessage(1);
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                workHandler.sendEmptyMessage(2);
            }
        });

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        handlerThread.quit();
        workHandler.removeCallbacksAndMessages(null);
    }

}

workerHandler内部运行的环境就已经是HandlerThread的独立线程环境了,缩一不允许在内部直接操作UI变化。

(完)

上一篇下一篇

猜你喜欢

热点阅读