• 一起学Android之Handler


    概述

    在Android开发中,有主线程(UI线程)和工作线程(Worker线程)之分,两个线程是相互独立的,并不能相互访问(主线程主要负责UI的更新,不能进行耗时的操作,工作线程主要负责耗时的操作,但不能进行UI的更新),所以要在两个线程之间进行数据传递,就需要Handler作为传递数据的桥梁。每一个Handler对象,都与独立的线程以及线程的消息队列有关。本文仅供学习分享使用。

    Handler逻辑

    1. Looper会从消息队列中,将消息对象取出。
    2. Looper会找到Message对象对应的Handler对象。
    3. Looper会调用Handler对象的handleMessage方法,用于处理对象。

    涉及知识点

    • Android线程:有主线程(UI线程)和工作线程(Worker线程)
    • Handler 允许发送和处理与线程相关的消息对列的可运行对象。
      • handleMessage (Message msg) 必须在子类进行重写的的处理消息的方法。
      • sendMessage (Message msg) 发送消息方法。
      • obtainMessage () 用于从全局消息池中获取一个新的对象。
    • Message 定义一个用于描述和任意数据对象的消息,此消息可以发送到Handler对象。
      • what 消息对象的标识符。
      • arg1,arg2 用于存储整型数据的值。
      • obj 可以接受任意的对象,用于存储消息的对象的值。
    • Thread 线程是一个可并发执行的单元。重写run方法来处理线程内容。

    Handler原理

    如下图所示:

    核心代码

    创建一个内部类继承Handler

     1  /*
     2     创建一个内部Handler类
     3      */
     4     class NetworkHandler extends Handler{
     5 
     6         @Override
     7         public void handleMessage(Message msg) {
     8             Log.i("DemoHandler", "run: thread id2="+Thread.currentThread().getName());
     9            String s = (String) msg.obj;
    10             txtInfo.setText(s);
    11         }
    12     }

    创建一个内部类,继承Thread

     1   /*
     2     创建一个线程内部类
     3      */
     4     class NetworkThread extends Thread{
     5         @Override
     6         public void run() {
     7             Log.i("DemoHandler", "run: thread id1="+Thread.currentThread().getName());
     8             //模拟网络获取,当执行时休眠2秒钟
     9             try {
    10                 Thread.sleep(2*1000);
    11             } catch (InterruptedException e) {
    12                 e.printStackTrace();
    13             }
    14             //通过handler将线程数据,发送到消息队列中
    15             //1. Looper将消息队列中的消息对象取出。
    16             //2. Looper找到消息对象对应的Handler对象
    17             //3. Looper将会调用handler对象中的handleMessage(Msg)方法,处理对象
    18             String s="这是一个线程中的数据";
    19             Message msg=handler.obtainMessage();
    20             msg.what=1;
    21             msg.obj=s;
    22             handler.sendMessage(msg);
    23         }
    24     }

    启动线程

    1  public  void click_me(View v){
    2         //点击事件中启动一个线程
    3         Thread thread=new NetworkThread();
    4         thread.start();
    5     }

    调试输出信息(两个分属不同的线程)

    1 04-25 22:56:37.424 18601-18786/com.hex.demohandler I/DemoHandler: run: thread id1=Thread-4
    2 04-25 22:56:39.425 18601-18601/com.hex.demohandler I/DemoHandler: run: thread id2=main
    3 04-25 22:56:55.491 18601-18800/com.hex.demohandler I/DemoHandler: run: thread id1=Thread-5
    4 04-25 22:56:57.492 18601-18601/com.hex.demohandler I/DemoHandler: run: thread id2=main

    备注

    大多数情况下,在worker thread中修改view是不可以的,小部分是可以的,如progressbar 。

  • 相关阅读:
    vim官方教程
    vim命令
    vim设置——/home/.vimrc设置
    Django中静态及媒体文件的引用设置
    博客园特效,拖动鼠标吸附线条
    机器学习工具Octave安装(Win10环境)
    【原】Coursera—Andrew Ng斯坦福机器学习(0)——课程地址和软件下载
    Anaconda 安装教程(Win10环境) Tensorflow安装
    博客园 设置各级标题样式
    Android WebView 捕捉点击的URL中的信息
  • 原文地址:https://www.cnblogs.com/hsiang/p/10801052.html
Copyright © 2020-2023  润新知