首页 > 其他分享 >Handler的基本使用和工作流程

Handler的基本使用和工作流程

时间:2022-09-05 13:23:08浏览次数:71  
标签:基本 Thread 流程 Handler 线程 msg UI public

一、Handler的基本使用

  • Handler一套Android消息传递机制,在多线程的应用场景中,将工作线程中需更新UI的操作信息传递到UI主线程,从而实现工作线程对UI的更新处理,最终实现异步消息的处理,多个线程并发更新UI的同时,保证线程安全。

  • 使用方式

    • Handler的使用方式 因发送消息到消息队列的方式不同而不同,共分为2种:使用Handler.sendMessage()、使用Handler.post()

    • 使用Handler.sendMessage(),新建Handler子类(内部类)

      public class MainActivity extends AppCompatActivity {
          
          public TextView mTextView;
          public Handler mHandler;
       
          // 步骤1:(自定义)新创建Handler子类(继承Handler类) & 复写handleMessage()方法
          class Mhandler extends Handler {
       
              // 通过复写handlerMessage() 从而确定更新UI的操作
              @Override
              public void handleMessage(Message msg) {
                  // 根据不同线程发送过来的消息,执行不同的UI操作
                  // 根据 Message对象的what属性 标识不同的消息
                  switch (msg.what) {
                      case 1:
                          mTextView.setText("执行了线程1的UI操作");
                          break;
                      case 2:
                          mTextView.setText("执行了线程2的UI操作");
                          break;
                  }
              }
          }
       
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
       
              mTextView = (TextView) findViewById(R.id.show);
       
              // 步骤2:在主线程中创建Handler实例
              mHandler = new Mhandler();
             
              // 采用继承Thread类实现多线程演示
              new Thread() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(3000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
       
                       // 步骤3:创建所需的消息对象
                       Message msg = Message.obtain();
                       msg.what = 1; // 消息标识
                       msg.obj = "A"; // 消息内存存放
       
                       // 步骤4:在工作线程中 通过Handler发送消息到消息队列中
                       mHandler.sendMessage(msg);
                  }
              }.start();
              // 步骤5:开启工作线程(同时启动了Handler)
       
              // 此处用2个工作线程展示
              new Thread() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(6000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      // 通过sendMessage()发送
                       // a. 定义要发送的消息
                       Message msg = Message.obtain();
                       msg.what = 2; //消息的标识
                       msg.obj = "B"; // 消息的存放
                       // b. 通过Handler发送消息到其绑定的消息队列
                       mHandler.sendMessage(msg);
                  }
              }.start();
       
          }
      }
      
    • 使用Handler.sendMessage(),匿名内部类

      public class MainActivity extends AppCompatActivity {
          
          public TextView mTextView;
          public Handler mHandler;
       
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
       
              mTextView = (TextView) findViewById(R.id.show);
       
              // 步骤1:在主线程中 通过匿名内部类 创建Handler类对象
              mHandler = new Handler(){
                  // 通过复写handlerMessage()从而确定更新UI的操作
                  @Override
                  public void handleMessage(Message msg) {
                      // 根据不同线程发送过来的消息,执行不同的UI操作
                      switch (msg.what) {
                          case 1:
                              mTextView.setText("执行了线程1的UI操作");
                              break;
                          case 2:
                              mTextView.setText("执行了线程2的UI操作");
                              break;
                      }
                  }
              };
              // 采用继承Thread类实现多线程演示
              new Thread() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(3000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                       // 步骤3:创建所需的消息对象
                       Message msg = Message.obtain();
                       msg.what = 1; // 消息标识
                       msg.obj = "A"; // 消息内存存放
       
                       // 步骤4:在工作线程中 通过Handler发送消息到消息队列中
                       mHandler.sendMessage(msg);
                  }
              }.start();
              // 步骤5:开启工作线程(同时启动了Handler)
       
              // 此处用2个工作线程展示
              new Thread() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(6000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      // 通过sendMessage()发送
                       // a. 定义要发送的消息
                       Message msg = Message.obtain();
                       msg.what = 2; //消息的标识
                       msg.obj = "B"; // 消息的存放
                       // b. 通过Handler发送消息到其绑定的消息队列
                       mHandler.sendMessage(msg);
                  }
              }.start();
          }
      }
      
    • 使用 Handler.post()

      public class MainActivity extends AppCompatActivity {
          
          public TextView mTextView;
          public Handler mHandler;
       
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
       
              mTextView = (TextView) findViewById(R.id.show);
       
              // 步骤1:在主线程中创建Handler实例
              mHandler = new Handler();
       
              // 步骤2:在工作线程中 发送消息到消息队列中 & 指定操作UI内容
              new Thread() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(3000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      // 通过psot()发送,需传入1个Runnable对象
                      mHandler.post(new Runnable() {
                          @Override
                          public void run() {
                              // 指定操作UI内容
                              mTextView.setText("执行了线程1的UI操作");
                          }
       
                      });
                  }
              }.start();
              // 步骤3:开启工作线程(同时启动了Handler)
       
              // 此处用2个工作线程展示
              new Thread() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(6000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      mHandler.post(new Runnable() {
                          @Override
                          public void run() {
                              mTextView.setText("执行了线程2的UI操作");
                          }
       
                      });
                  }
              }.start();
          }
      }
      

二、Handler机制的工作流程

  • 异步通信准备

  • 消息发送

  • 消息循环

  • 消息处理

标签:基本,Thread,流程,Handler,线程,msg,UI,public
From: https://www.cnblogs.com/bkyxiaozhi/p/16657753.html

相关文章

  • 力扣227(java)-基本计算器Ⅱ(中等)
    题目:给你一个字符串表达式s,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。你可以假设给定的表达式总是有效的。所有中间结果将在 [-231,231......
  • Unreal引擎启动流程及耗时分析
    引擎版本:4.18部分耗时流程结构概述:Winmain └GuardedMain └EnginePreInit └FEngineLoop::PreInit └LoadPreInitModules() └AppInit() └Proces......
  • ENVI自动配准流程化工具的另类用法
    这里说的另类用法是指:只想利用自己手动添加的同名点用于图像配准,而不希望工具自动找点。这种需求一般用于无法自动找点的情况,比如卫星图像与DRG之类的线划图进行配准时。......
  • MySQL安装流程
    一、下载MySQL  Mysql官网下载地址:https://downloads.mysql.com/archives/installer/  1.选择想要安装的版本,点击Download下载  本篇文章选择的是......
  • 16.普通参数与基本注解-@ModelAttribute
    抄的网上的分析,但是也要用自己的话理解一遍用法1:用在入参运用在参数上,会将客户端传递过来的参数按名称注入到指定对象中,并且会将这个对象自动加入ModelMap中,便于View层使......
  • JS | getBoundingClientRect()方法的基本使用
    Element.getBoundingClientRect()方法返回一个DOMRect对象,其提供了元素的大小及其相对于视口的位置。返回的对象中有几个只读属性:width/x:元素矩形的宽度height/y......
  • Linux 服务器安全(基本)
    Linux服务器安全     版本标识V1编制单位李斌编制日期2020年7月 第一节1、红帽linux的好处2、linux企业版发行的类型3......
  • 数组的基本用例
    数组的基本用例int[]arr={1,7,3,4,5};//定义一个数组遍历并打印数组内所有元素for(inti=0;i<arr.length;i++){System.out.println(arr[i]);......
  • zabbix的基本使用
    目录zabbix服务端web界面介绍(Monitoring)监控选项栏设置(Services)服务选项栏(lnventory)清单选项栏(Reports)报告选项栏(Configuration)配置选项栏(Administration)管理选项卡zabbix......
  • 第二章 操作系统基本原理(操作系统知识)
    一:操作系统概述 二:进程管理       PV操作与信号量的处理相关,P表示通过的意思,V表示释放的意思。              三:......