Message(消息):
一. Message的字段:
在Android中,Message作为线程之间(主要是子线程和UI主线程之间)数据交换的载体,通过Handler去传递。它包含几个常用的字段:
1.arg1和arg2两个int类型的字段:主要在线程之间需要传递简单的int类型的数据时使用。
2.what字段:int类型,主要用于标识一个Message。当在子线程中定义一个Message时,通常指定what的值为一个int常量,该Message传递到主线程时,我们通过what的值识别该Message。
3.obj字段:是一个任意类型的对象,线程之间要交换的数据,主要是通过该字段来存储。
二. 获得Massage对象
1. 通过构造函数获得Message对象,Message有一个构造函数:
1 public
Message.obtain()有多个重载方法。使用Message的构造函数来创建Message对象需要重新分配一块新的内容,而通过 Message.obtain()和Handler.obtainMessage()方法主要从全局消息槽中使用被回收的对象来创建Message,这样节省了一定的内存。
例子:在子线程中通过Message构造函数创建Message对象,并通过Handler传递到主线程中。
1 package zst.message01;
2 import android.os.Bundle;
3 import android.os.Handler;
4 import android.os.Message;
5 import android.app.Activity;
6 import android.view.Menu;
7 import android.view.View;
8 import android.view.View.OnClickListener;
9 import android.widget.Button;
10 public class MainActivity extends Activity implements OnClickListener {
11 private Button button01;
12
13 public static final int ONE = 1;
14
15
16 //在主线程中创建的Handler对象,通常定义成static
17 public static Handler handler = new Handler(){
18 @Override
19 public void handleMessage(Message msg) {
20 switch (msg.what) {
21 case ONE:
22 System.out.println("第一个Message-->" + "arg1=" + msg.arg1 + ",arg2=" + msg.arg2 + ",obj=" + msg.obj);
23 break;
24 default:
25 break;
26 }
27 }
28
29
30 };
31
32
33 @Override
34 protected void onCreate(Bundle savedInstanceState) {
35 super.onCreate(savedInstanceState);
36 setContentView(R.layout.activity_main);
37 button01 = (Button) findViewById(R.id.button01);
38 button01.setOnClickListener(this);
39 }
40
41 @Override
42 public void onClick(View v) {
43 if(v.getId() == R.id.button01){
44 //启动一个子线程
45 new Thread(new Runnable() {
46
47 @Override
48 public void run() {
49 //获得Message对象的第一种方法:使用构造函数创建Message,这种方法不推荐使用
50 Message message = new Message();
51 message.arg1 = 100;
52 message.arg2 = 200;
53 message.what = ONE; //用于标识Message
54 message.obj = "Message_01";
55 //发送Message到主线程中
56 handler.sendMessage(message);
57
58 }
59
60 }).start();
61
62 }
63
64
65 }
66 }
输出:
2. 通过 public static Message obtain() 方法获得Message对象
1 //获得Message对象的第二种方法
2 Message message = Message.obtain();
3 message.arg1 = 100;
4 message.arg2 = 200;
5 message.what = TWO; //用于标识Message
6 message.obj = "Message_02";
7 handler.sendMessage(message);
public static Message obtain()方法的源码如下:
1 // sometimes we store linked lists of these things
2 /*package*/ Message next;
3 private static final Object sPoolSync = new Object();
4 private static Message sPool;
5 private static int sPoolSize = 0;
6 private static final int MAX_POOL_SIZE = 50;
7 /**
8 * Return a new Message instance from the global pool. Allows us to
9 * avoid allocating new objects in many cases.
10 */
11 public static Message obtain() {
12 synchronized (sPoolSync) {
13 if (sPool != null) {
14 Message m = sPool;
15 sPool = m.next;
16 m.next = null;
17 sPoolSize--;
18 return m;
19 }
20 }
21 return new Message();
22 }
节省了一定的内存。如果sPool为null时,即消息槽为空,没有Message,这时才调用Message的构造函数来创建一个Message对象给我们。
3. 通过 public static Message obtain(Handler h) 方法获得Message对象
1 //获得Message对象的第三种方法:
2 Message message = Message.obtain(handler);
3 message.arg1 = 100;
4 message.arg2 = 200;
5 message.what = THREE; //用于标识Message
6 message.obj = "Message_03";
7 //发送Message
8 message.sendToTarget();
public static Message obtain(Handler h)方法的源码如下:
1 /**
2 * Same as {@link #obtain()}, but sets the value for the <em>target</em> member on the Message returned.
3 * @param h Handler to assign to the returned Message object's <em>target</em> member.
4 * @return A Message object from the global pool.
5 */
6 public static Message obtain(Handler h) {
7 Message m = obtain();
8 m.target = h;
9 return m;
10 }
public static Message obtain()方法从全局消息槽中返回一个Message对象给我们,然后把传入的Handler对象参数当成发送和接收该Message对象的目标Handler对象。由于该方法内部已经指定了处理Message对象的目标Handler对象,所以在发送Message消息时,不会再调用Handler对象的sendMessage(message)方法,而是直接使用Message对象的sendToTarget()方法发送。
4. 通过public static Message obtain(Handler h, int what)方法获得
1 //获得Message对象的第四种方法:
2 Message message = Message.obtain(handler, FOUR);
3 message.arg1 = 100;
4 message.arg2 = 200;
5 message.obj = "Message_04";
6 message.sendToTarget();
public static Message obtain(Handler h, int what)方法的源码如下:
1 /**
2 * Same as {@link #obtain()}, but sets the values for both <em>target</em> and
3 * <em>what</em> members on the Message.
4 * @param h Value to assign to the <em>target</em> member.
5 * @param what Value to assign to the <em>what</em> member.
6 * @return A Message object from the global pool.
7 */
8 public static Message obtain(Handler h, int what) {
9 Message m = obtain();
10 m.target = h;
11 m.what = what;
12 return m;
13 }
public static Message obtain(Handler h)方法的源码类似,都是先 通过 public static Message obtain()方法从全局消息槽中获得Message对象,再指定目标Handler对象,同时也指定Message的what字段值。
obtain()的重载方法也是这样,不同点是在创建Message对象时,同时指定Message的不同字段值。如下:
public static Message obtain(Handler h, int what, Object obj)方法源码:
1 /**
2 * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, and <em>obj</em>
3 * members.
4 * @param h The <em>target</em> value to set.
5 * @param what The <em>what</em> value to set.
6 * @param obj The <em>object</em> method to set.
7 * @return A Message object from the global pool.
8 */
9 public static Message obtain(Handler h, int what, Object obj) {
10 Message m = obtain();
11 m.target = h;
12 m.what = what;
13 m.obj = obj;
14 return m;
15 }
public static Message obtain(Handler h, int what, int arg1, int arg2, Object obj)方法源码:
1 /**
2 * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,
3 * <em>arg1</em>, <em>arg2</em>, and <em>obj</em> members.
4 *
5 * @param h The <em>target</em> value to set.
6 * @param what The <em>what</em> value to set.
7 * @param arg1 The <em>arg1</em> value to set.
8 * @param arg2 The <em>arg2</em> value to set.
9 * @param obj The <em>obj</em> value to set.
10 * @return A Message object from the global pool.
11 */
12 public static Message obtain(Handler h, int what,
13 int arg1, int arg2, Object obj) {
14 Message m = obtain();
15 m.target = h;
16 m.what = what;
17 m.arg1 = arg1;
18 m.arg2 = arg2;
19 m.obj = obj;
20 return m;
21 }
public static Message obtain(Handler h, int what, int arg1, int arg2)方法源码:
1 /**
2 * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,
3 * <em>arg1</em>, and <em>arg2</em> members.
4 *
5 * @param h The <em>target</em> value to set.
6 * @param what The <em>what</em> value to set.
7 * @param arg1 The <em>arg1</em> value to set.
8 * @param arg2 The <em>arg2</em> value to set.
9 * @return A Message object from the global pool.
10 */
11 public static Message obtain(Handler h, int what, int arg1, int arg2) {
12 Message m = obtain();
13 m.target = h;
14 m.what = what;
15 m.arg1 = arg1;
16 m.arg2 = arg2;
17 return m;
18 }
三. Message还可以携带Bundle对象
添加Bundle对象
1 Message message = Message.obtain(handler, EIGHT, 100, 200);
2 message.obj = "Message_08";
3 Bundle b = new Bundle();
4 b.putString("name", "张三");
5 message.setData(b);
6 message.sendToTarget();
取出Bundle对象
1
例子源码:D:\Android\workspace\ThreadAndAsync\Message01