一、 Handler

1、使用

  • 在主线程中定义一个 Handler, 重写 handleMessage 方法

  //在主线程中定义一个Handler
  private Handler handler=new Handler(){
      //这个方法是在主线程中执行的
      @Override
      public void handleMessage(Message msg) {
         tv_result.setText(msg.obj.toString());
      }
  };
  • 在子线程中使用主线程中创建的handler 发送消息

    Message msg=new Message();
    msg.obj=content;
    handler.sendMessage(msg);//发消息

2、handler 原理

线程是不能直接操作UI线程的,需要通过 handler,首先发送到(messagequeue)消息队列当中,然后Looper 会不断的循环

得到这条消息,再通过 handleMessage 方法执行得到消息

        handler 的作用是用来发消息和处理消息的
        Looper 的作用是去消息队列 (messagequeue) 中取消息
        Looper 是在主线程一创建就有了

Android  消息机制.png

3、Message what 属性的使用

<1> 设置 what 的 值

    Message msg=new Message();
    msg.what=REQUESTEXCEPTION;
    handler.sendMessage(msg);

<2>在 handleMessage 方法中进行判断,执行不同操作

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what){
            case REQUESTSUCCESS: //请求成功
                tv_result.setText(msg.obj.toString());
                break;
            case REQUESTNOTFIND: //目标资源不存在
                Toast.makeText(MainActivity.this, "目标资源不存在", Toast.LENGTH_SHORT).show();
                break;
            case REQUESTEXCEPTION: //异常
                Toast.makeText(MainActivity.this, "服务器忙 请稍等。。。", Toast.LENGTH_SHORT).show();
        }
    }

关于 Message: 可以通过 Message msg=Message.obtain(); ,这样的方式来创建,减少对象的创建。

二、runOnUIThread()

实际上是对 handler 的封装, 不管在什么位置调用,都是运行在UI线程当中

     如果仅仅只是更新UI,使用这个就可以了,**但是如果发送消息、数据传递,就是必须使用  **
   runOnUiThread(new Runnable() {
        @Override
       public void run() {
           //run 方法一定执行在 UI线程当中
       }
   });

三、 Handler 相关 API

延迟执行

Tyep1: 可以直接执行UI操作

   new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
           // 对应操作
       }
   },5000);

Type2: 不可以直接执行UI操作

    Timer timber=new Timer();
    TimerTask tast=new TimerTask() {
        @Override
        public void run() {
            //相关操作
            Log.e(TAG, "run: Tiger" );
        }
    };    
    //三秒后执行
    //timber.schedule(tast,5000);
    //三秒后没隔一秒执行一次 run 方法
    timber.schedule(tast,5000,1000);
Last modification:July 12th, 2020 at 07:56 pm