上面的文章我们演示了如何把一个Message由子线程发送给主线程,但是如何将一个Message从主线程发送给子线程呢?子线程在默认的情况下是没有Looper的,也就没有可能操作子线程的消息队列。我们通过查API文档可以看到:
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.
Most interaction with a message loop is through the Handler class.
大概意思是,线程在默认情况下是没有Looper的,但是可以通过调用Prepare()方法来运行一个loop,然后使用loop()方法来处理消息直到loop结束。通常的使用方式是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) { // process incoming
// messages here
}
};
Looper.loop();
}
} |
例程如下,基本过程是这样的,启动主线程,然后启动子线程,子线程注册Looper,主线程发送一个Message给子线程,然后子线程的handler处理此消息,再把此消息发送给主线程的消息队列,主线程空间显示此消息~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
| /**
* MessageExample4.java
* com.test.Message
*
* Function: TODO
*
* ver date author
* ──────────────────────────────────
* 2011-3-23 Leon
*
* Copyright (c) 2011, TNT All Rights Reserved.
*/
package com.test.Message;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* ClassName:MessageExample4 主线程如何传递消息给子线程 Function: TODO ADD FUNCTION Reason:
* TODO ADD REASON
*
* @author Leon
* @version
* @since Ver 1.1
* @Date 2011-3-23
*/
public class MessageExample4 extends Activity implements OnClickListener {
private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
private final int FP = LinearLayout.LayoutParams.FILL_PARENT;
public TextView tv;
private Button btn, btn2;
private Handler h;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
btn = new Button(this);
btn.setId(101);
btn.setText("test looper");
btn.setOnClickListener(this);
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(100, 50);
param.topMargin = 10;
layout.addView(btn, param);
btn2 = new Button(this);
btn2.setId(102);
btn2.setText("exit");
btn2.setOnClickListener(this);
layout.addView(btn2, param);
tv = new TextView(this);
tv.setTextColor(Color.WHITE);
tv.setText("");
LinearLayout.LayoutParams param2 = new LinearLayout.LayoutParams(FP, WC);
param2.topMargin = 10;
layout.addView(tv, param2);
setContentView(layout);
// 启动子线程
new myThread().start();
}
public void onClick(View v) {
switch (v.getId()) {
case 101:
String obj = "mainThread";
Message m = h.obtainMessage(1, 1, 1, obj);
h.sendMessage(m);
break;
case 102:
finish();
break;
}
}
// ------------------------------------------------------
class EHandler extends Handler {
public EHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
tv.setText((String) msg.obj);
}
}
// ------------------------------------------------------
class myThread extends Thread {
private EHandler mHandler;
public void run() {
Looper.prepare();
h = new Handler() {
public void handleMessage(Message msg) {
EHandler ha = new EHandler(Looper.getMainLooper());
String obj = (String) msg.obj + ", myThread";
Message m = ha.obtainMessage(1, 1, 1, obj);
ha.sendMessage(m);
}
};
Looper.loop();
}
}
} |
本文章及代码由傻蛋整理及测试,转载请注明