概述

在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

  /*
创建一个内部Handler类
*/
class NetworkHandler extends Handler{ @Override
public void handleMessage(Message msg) {
Log.i("DemoHandler", "run: thread id2="+Thread.currentThread().getName());
String s = (String) msg.obj;
txtInfo.setText(s);
}
}

创建一个内部类,继承Thread

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

启动线程

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

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

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

备注

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

最新文章

  1. EditText 显示明文和密码
  2. 采用UDP协议的PIC32MZ ethernet bootloader
  3. db2 中文表名和字段
  4. lintcode:Number of Islands 岛屿的个数
  5. 一种快速求fibonacci第n个数的算法
  6. Hibernate session.saveOrUpdate()方法
  7. Java中对不变的 data和object reference 使用 final
  8. 【iOS】Swift扩展extension和协议protocol
  9. aria-label
  10. ☆ [HNOI2012] 永无乡 「平衡树启发式合并」
  11. idea新建一个spring项目,图解
  12. segmentController
  13. 【实践练习一】Git以及Github的使用
  14. ES6之字符串扩展
  15. 请问下.net俱乐部这个组织现在还存在么?
  16. ORM数据库框架 SQLite ORMLite MD
  17. 【C#公共帮助类】JsonHelper 操作帮助类
  18. ubuntu 安装 openssh-server,xinetd,vmware tools
  19. SHT20 IIC 寄存器概述
  20. c#连接oracle遇到的问题

热门文章

  1. 规范git commit提交记录和版本发布记录
  2. windows环境下Git的安装部署
  3. Android Studio 安装教程
  4. Python爬虫实战:爬取腾讯视频的评论
  5. java之java.io.File的相关方法
  6. 关于css布局的记录(一) --table和flex布局
  7. Python小技巧:打印出来的文本文档中间有空格
  8. c++11 auto 与auto& 遍历vector区别
  9. iOS引导页(开局滚动效果)
  10. 请确保二进制储存在指定的路径中,或者调试他以检查该二进制或相关的DLL文件