最简单的Handler、Looper、Message使用指南一(附github源码)

前言

什么是子线程?什么是主线程?为什么需要使用Handler?子线程和主线程怎么通信?

主线程是我们程序进程在创建的时候,调用ActivityThread的main入口,Looper.prepareMainLooper创建消息队列,接受activity 、window等消息,包括视图渲染。

我们知道Android的界面绘制是1秒钟60帧,也就是1000/60=16ms绘画一帧,如果我们有一些耗时操作,比如下载图片(花费2s),如果我们放在主线程下载,会阻塞主线程,让主线程不能处理消息2s,反映到界面就是程序无响应2s。所以在这种情况下,我们需要创建一个子线程,等子线程的图片下载完之后再通知主线程,把图片设置到图片视图上。

那么子线程和主线程怎么通信呢?这就要用我们的Handler了,这篇文章主要是讲怎么使用Handler,子线程和主线程通信的底层原理我会单独写一篇文章分析,走进源码,Android面试最常见Handler、Looper、Message问题总结与解答

【转载请注明出处:最简单的Handler、Looper、Message使用指南一(附github源码)  CSDN 王智博

源码下载

github:https://github.com/samwangzhibo/LoveStudy (不会使用github导入代码的同学,戳这)

举个栗子

比如我们要实现在主线程打印子线程传递过来数据这个需求,我们实现一个子线程一直发送数据,主线程获取数据并且用TextView打印出子线程传过来的数据。

Let do it!

第一步我们创建一个一直发送数据的子线程

class SendThread extends Thread {
        int num = 0;
        boolean isEnd = false;
        private final int DURATION_SLEEP = 1000;

        void setEnd(boolean end) {
            isEnd = end;
        }

        @Override
        public void run() {
            super.run();
            while (!isEnd) {
                mainHandler.sendMessage(Message.obtain(mainHandler, WHAT_MODIFY_TV, num++));
                try {
                    //不释放资源 休眠
                    Thread.sleep(DURATION_SLEEP);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

其中最重要的是Handler发送数据的方法,sendMessage(Message msg)

第二步在主线程中获取数据并且展示

Handler mainHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case WHAT_MODIFY_TV:
                    tvReciver.setText("接受子线程传递的参数:" + msg.obj);
                    break;
                default:
            }
        }
    };

其中子线程传递过来的数据是存放在Handler handleMessage中的Message.obj里面

总结

1.在主线程(需要获取数据的线程)创建Handler

Handler mainHandler = new Handler(Looper.getMainLooper())

2.在子线程发送数据,(num++便是携带的数据)

mainHandler.sendMessage(Message.obtain(mainHandler, WHAT_MODIFY_TV, num++));

3.重写Handler的handleMessage方法,获取子线程的数据

public void handleMessage(Message msg) {
      switch (msg.what) {
           case WHAT_MODIFY_TV:
                tvReciver.setText("接受子线程传递的参数:" + msg.obj);
                break;
           default:
       }
  }

扩展

如果想要看Handler为啥可以在主线程和子线程通信,请戳楼主的面试文章

走进源码,Android面试最常见Handler、Looper、Message问题总结与解答

源码下载

github:https://github.com/samwangzhibo/LoveStudy (不会使用github导入代码的同学,戳这)

全部代码

public class HandlerActivity extends Activity {
    private static final int WHAT_MODIFY_TV = 100;
    TextView tvReciver;
    SendThread sendThread;
    Handler mainHandler2 = new Handler();
    Handler mainHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case WHAT_MODIFY_TV:
                    tvReciver.setText("接受子线程传递的参数:" + msg.obj);
                    break;
                default:
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        tvReciver = findViewById(R.id.tv_receiver);
        //开启一个子线程,一直朝主线程发送数据
        sendThread = new SendThread();
        sendThread.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //退出时候切记 关闭线程 回收资源 !!!!
        sendThread.setEnd(true);
    }

    class SendThread extends Thread {
        int num = 0;
        boolean isEnd = false;
        private final int DURATION_SLEEP = 1000;

        void setEnd(boolean end) {
            isEnd = end;
        }

        @Override
        public void run() {
            super.run();
            while (!isEnd) {
                mainHandler.sendMessage(Message.obtain(mainHandler, WHAT_MODIFY_TV, num++));
                try {
                    //不释放资源 休眠
                    Thread.sleep(DURATION_SLEEP);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/wangzhibo666/article/details/86516422
今日推荐