Handler消息传递机制

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.classic
18 
19     };
20 
21     int currentImageId = 0;
22 
23  
24 
25     @Override
26 
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             @Override
40 
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             @Override
60 
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<Integer> nums = new ArrayList<Integer>();
 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 }

 

posted @ 2016-05-15 16:12  NeonCowboy  阅读(195)  评论(0编辑  收藏  举报