Handler的运行机制

Handler的运行机制

Handler的作用:

当我们需要在子线程处理耗时的操作(例如访问网络,数据库的操作),而当耗时的操作完成后,需要更新UI,这就需要使用Handler来处理,因为子线程不能做更新UI的操作。Handler能帮我们很容易的把任务(在子线程处理)切换回它所在的线程。简单理解,Handler就是解决线程和线程之间的通信的。

Handler的使用

使用的handler的两种形式:
1.在主线程使用handler;
2.在子线程使用handler。

在主线程使用handler的示例:

    public class TestHandlerActivity extends AppCompatActivity {


        private static final String TAG = "TestHandlerActivity";

        private Handler mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //获得刚才发送的Message对象,然后在这里进行UI操作
                Log.e(TAG,"------------> msg.what = " + msg.what);
            }
        };


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

        private void initData() {

            //开启一个线程模拟处理耗时的操作
            new Thread(new Runnable() {
                @Override
                public void run() {

                    SystemClock.sleep(2000);
                    //通过Handler发送一个消息切换回主线程(mHandler所在的线程)
                    mHandler.sendEmptyMessage(0);
                }
            }).start();

        }   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

这里写图片描述

在主线程使用handler很简单,只需在主线程创建一个handler对象,在子线程通过在主线程创建的handler对象发送Message,在handleMessage()方法中接受这个Message对象进行处理。通过handler很容易的从子线程切换回主线程了。

那么来看看在子线程中使用是否也是如此。

 public class TestHandlerActivity extends AppCompatActivity {


        private static final String TAG = "TestHandlerActivity";
        //主线程中的handler
        private Handler mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //获得刚才发送的Message对象,然后在这里进行UI操作
                Log.e(TAG,"------------> msg.what = " + msg.what);
            }
        };
        //子线程中的handler
        private Handler mHandlerThread = null;

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

        private void initData() {

            //开启一个线程模拟处理耗时的操作
            new Thread(new Runnable() {
                @Override
                public void run() {

                    SystemClock.sleep(2000);
                    //通过Handler发送一个消息切换回主线程(mHandler所在的线程)
                    mHandler.sendEmptyMessage(0);
                    //在子线程中创建Handler
                    mHandlerThread = new Handler(){
                        @Override
                        public void handleMessage(Message msg) {
                            super.handleMessage(msg);
                            Log.e("sub thread","---------> msg.what = " + msg.what);
                        }
                    };

                    mHandlerThread.sendEmptyMessage(1);
                }
            }).start();

        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

这里写图片描述

程序崩溃了。报的错误是没有在子线程调用Looper.prepare()的方法。而为什么在主线程中使用不会报错?通过源码的分析可以解析这个问题。

在子线程中正确的使用Handler应该是这样的。

 public class TestHandlerActivity extends AppCompatActivity {


        private static final String TAG = "TestHandlerActivity";

        //主线程的Handler
        private Handler mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //获得刚才发送的Message对象,然后在这里进行UI操作
                Log.e(TAG,"------------> msg.what = " + msg.what);
            }
        };
        //子线程中的Handler
        private Handler mHandlerThread = null;

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

        private void initData() {

            //开启一个线程模拟处理耗时的操作
            new Thread(new Runnable() {
                @Override
                public void run() {

                    SystemClock.sleep(2000);
                    //通过Handler发送一个消息切换回主线程(mHandler所在的线程)
                    mHandler.sendEmptyMessage(0);

                    //调用Looper.prepare()方法
                    Looper.prepare();

                    mHandlerThread = new Handler(){
                        @Override
                        public void handleMessage(Message msg) {
                            super.handleMessage(msg);
                            Log.e("sub thread","---------> msg.what = " + msg.what);
                        }
                    };

                    mHandlerThread.sendEmptyMessage(1);

                    //调用Looper.loop()方法
                    Looper.loop();
                }
            }).start();

        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

这里写图片描述

可以看到,通过调用Looper.prepare()运行正常,handleMessage方法中就可以接收到发送的Message。

至于为什么要调用这个方法呢?去看看源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值