欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

一起学Android之Handler

程序员文章站 2022-06-20 14:34:34
一起学Android之Handler,简单介绍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原理

如下图所示:

一起学Android之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 。