博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Handler消息传递机制
阅读量:5314 次
发布时间:2019-06-14

本文共 4289 字,大约阅读时间需要 14 分钟。

Handler简介

Android 中规定,只允许UI线程修改Activity中的UI组件。当程序第一次启动的时候,就启动了一条主线程(Main Thread),通常被称为UI线程。如果新启动的线程想要改变界面组件里的属性值,则要借助Handler的消息传递机制。

 

程序实例:

//布局文件仅含有一个ImageView组件。

 

1 public class MainActivity extends AppCompatActivity { 2  3   4  5   6  7     int[] imageIds = new int[]{ 8  9             R.drawable.java,10 11             R.drawable.ee,12 13             R.drawable.ajax,14 15             R.drawable.xml,16 17             R.drawable.classic18 19     };20 21     int currentImageId = 0;22 23  24 25     @Override26 27     protected void onCreate(Bundle savedInstanceState) {28 29         super.onCreate(savedInstanceState);30 31         setContentView(R.layout.activity_main);32 33  34 35         final ImageView show = (ImageView) findViewById(R.id.show);36 37         final Handler myHandler = new Handler() {38 39             @Override40 41             // import android.os.Handler;42 43             public void handleMessage(Message msg) {44 45                 if (msg.what == 0x1233) {46 47                     show.setImageResource(imageIds[currentImageId++ % imageIds.length]);48 49                 }50 51             }52 53         };54 55  56 57         new Timer().schedule(new TimerTask() {58 59             @Override60 61             public void run() {62 63                 myHandler.sendEmptyMessage(0x1233);64 65             }66 67         }, 0, 1200);68 69     }70 71 }

 

 

TimerTask对象本质是启动一条新线程,因此不能对UI组件进行更改。

程序通过Timer方法定时传递一个空的消息(0x1233)给myHandler,然后主线程中handleMessage来处理该消(0X1233

 

Handler 工作原理

  • Message:  Handler接受和处理的消息对象。
  • Looper:  每个线程只有一个Looper,它负责管理MessageQueue,会不断从MessageQueue中取出消息,并将消息分给对应的Handler处理。
  • MessageQueue:  Looper负责管理。它采用先进先出的方式来管理Message
  • Handler:  他能把消息发送给Looper 管理的MessageQueue,并负责处理Looper 分给它的消息。

 

在线程中使用Handler的步骤:

  1. 调用Looper preper() 方法为当前线程创建Looper对象,创建Looper对象时,它的构造器会创建与之配套的MessageQueue
  2. 有了Looper后,创建Handler子类的实例,重写handlrMessage()方法,该方法负责处理来自其他线程的消息。
  3. 调用Looperloop()方法启动Looper

 

实例:

//布局文件中包含一个按键和一个文本框

//其中按键中包含属性onClick = "cal"         cal  activity中声明的方法。

1    2   3 public class MainActivity extends AppCompatActivity {  4   5    6   7     static final String UPPER_NUM = "upper";  8   9     EditText etNum; 10  11     CalThread calThread; 12  13   14  15     @Override 16  17     protected void onCreate(Bundle savedInstanceState) { 18  19         super.onCreate(savedInstanceState); 20  21         setContentView(R.layout.activity_main); 22  23   24  25         etNum = (EditText) findViewById(R.id.etNum); 26  27         calThread = new CalThread(); 28  29         calThread.start(); 30  31     } 32  33   34  35     public void cal(View source){ 36  37         Message msg = new Message(); 38  39         msg.what = 0x1233; 40  41         Bundle bundle = new Bundle(); 42  43         bundle.putInt(UPPER_NUM, Integer.parseInt(etNum.getText().toString())); 44  45         msg.setData(bundle); 46  47         calThread.mHandler.sendMessage(msg); 48  49     } 50  51   52  53     private class CalThread extends Thread { 54  55   56  57         public Handler mHandler; 58  59         @Override 60  61         public void run() { 62  63             Looper.prepare(); 64  65             mHandler = new Handler(){ 66  67                 @Override 68  69                 public void handleMessage(Message msg) { 70  71                     if(msg.what ==  0x1233){ 72  73                         int upper = msg.getData().getInt(UPPER_NUM); 74  75                         List
nums = new ArrayList
(); 76 77 outer: 78 79 for(int i = 2; i <= upper; i++){ 80 81 for(int j =2; j <= Math.sqrt(i); j++){ 82 83 if(i != 2 && i % j == 0){ 84 85 continue outer; 86 87 } 88 89 } 90 91 nums.add(i); 92 93 } 94 95 Toast.makeText(MainActivity.this, nums.toString(), 96 97                   Toast.LENGTH_LONG).show(); 98 99 }100 101 }102 103 };104 105 Looper.loop();106 107 }108 109 }110 111 }

 

转载于:https://www.cnblogs.com/NeonCowboy/p/5495415.html

你可能感兴趣的文章
Oracle树形结构查询之prior的理解
查看>>
segnet 编译与测试
查看>>
linux lsof/netstat查看进程和端口号相关命令:
查看>>
解决Maven管理项目update Maven时,jre自动变为1.5
查看>>
学习笔记:log4j.properties配置
查看>>
flask sqlalchemy 单表查询
查看>>
操作系统,,,也考完了【流坑】
查看>>
[No0000DB]C# FtpClientHelper Ftp客户端上传下载重命名 类封装
查看>>
读<jquery 权威指南>[7]-性能优化与最佳实践
查看>>
ssh key生成
查看>>
JDeveloper中文乱码问题
查看>>
VS2008、VS2010中如何屏蔽讨厌的MSVCR*.dll的引用
查看>>
【mongoDB运维篇③】replication set复制集
查看>>
java--用 * 打印出各种图形(新手请进)
查看>>
【知识分享】异步调用与多线程的区别
查看>>
win7 32位 安装opencv-python后,运行时提示 "from .cv2 import *: DLL load failed: 找不到指定的模块" 的解决办法...
查看>>
安装SQLserver2008
查看>>
哎,累死了~..~
查看>>
查看MySQL的当前日期
查看>>
vmware 克隆后Linux没有eth网卡只有lo
查看>>