n在
Looper.loop()方法运行开始后,循环地按照接收顺序取出
Message Queue里面的非
NULL的
Message。
n 一开始
Message Queue里面的
Message都是
NULL的。当
Handler.sendMessage(Message)到
Message Queue,该函数里面设置了那个
Message对象的
target属性是当前的
Handler对象。随后
Looper取出了那个
Message,则调用该
Message的
target指向的
Hander的
dispatchMessage函数对
Message进行处理。
¨ 在
dispatchMessage方法里,如何处理
Message则由用户指定,三个判断,优先级从高到低:
n Message里面的
Callback,一个实现了
Runnable接口的对象,其中
run函数做处理工作;
n Handler里面的
mCallback指向的一个实现了
Callback接口的对象,由其
handleMessage进行处理;
n 理消息
Handler对象对应的类继承并实现了其中
handleMessage函数,通过这个实现的
handleMessage函数处理消息。
n
Handler处理完该
Message (update UI) 后,
Looper则设置该
Message为
NULL,以便回收!
Android
使用
mHandler = new MyHandler(Looper.getMainLooper());
可诞生用来处理
main线程的
Handler对象;其中,
MyHandler是自已实现的
Handler的子类别。
同线程内不同组件间的消息传递
public class Activity1 extends Activity implements OnClickListener{
Button button = null;
TextView text = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity1);
button = (Button)findViewById(R.id.btn);
button.setOnClickListener(this);
text = (TextView)findViewById(R.id.content);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn:
Looper looper = Looper.myLooper();//取得当前线程里的looper
MyHandler mHandler = new MyHandler(looper);//构造一个handler使之可与looper通信
mHandler.removeMessages(0);
String msgStr = "主线程不同组件通信:消息来自button";
Message m = mHandler.obtainMessage(1, 1, 1, msgStr);//构造要传递的消息
mHandler.sendMessage(m);//发送消息:系统会自动调用handleMessage方法来处理消息
break;
}
}
private class MyHandler extends Handler{
public MyHandler(Looper looper){
super(looper);
}
public void handleMessage(Message msg) {//处理消息
text.setTex
……
}
}
子线程传递消息给主线程
private
class
MyThread
extends
Thread{
public
void
run() {
Looper curLooper = Looper.
myLooper
();
Looper mainLooper = Looper.
getMainLooper
();
String msg ;
if(curLooper==null){
mHandler
=
new
MyHandler(mainLooper);
msg =
"curLooper is null";
}else{
mHandler
=
new
MyHandler(curLooper);
msg =
"This is curLooper";
}
mHandler.removeMessages(0);
Message m =
mHandler.obtainMessage(1, 1, 1, msg);
mHandler.sendMessage(m);
}
}
}
Android另外提供了一个工具类:AsyncTask。它使得UI thread的使用变得异常简单。它使创建需要与用户界面交互的长时间运行的任务变得更简单,不需要借助线程和Handler即可实现。
AsyncTask的构造函数的参数设置需要看明白:AsyncTask
Params对应doInBackground(Params...)的参数类型。而new AsyncTask().execute(Params... params),就是传进来的Params数据,你可以execute(data)来传送一个数据,或者execute(data1, data2, data3)这样多个数据。
Progress对应onProgressUpdate(Progress...)的参数类型;
Result对应onPostExecute(Result)的参数类型。
当以上的参数类型都不需要指明某个时,则使用Void,注意不是void。
实现AsyncTask中定义的下面一个或几个方法
onPreExecute() 开始执行前的准备工作;
doInBackground(Params...) 开始执行后台处理,可以调用publishProgress方法来更新实时的任务进度;
onProgressUpdate(Progress...) 在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result) 执行完成后的操作,传送结果给UI 线程。
这4个方法都不能手动调用。而且除了doInBackground(Params...)方法,其余3个方法都是被UI线程所调用的,所以要求:
AsyncTask的实例必须在UI thread中创建;
AsyncTask.execute方法必须在UI thread中调用;
((Button) findViewById(R.id.load_AsyncTask)).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
data = null;
data = new ArrayList();
adapter = null;
//显示ProgressDialog放到AsyncTask.onPreExecute()里
//showDialog(PROGRESS_DIALOG);
new ProgressTask().execute(data);
}
});
private class ProgressTask extends AsyncTask
, Void, Integer> {
/* 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。*/
@Override
protected void onPreExecute() {
// 先显示ProgressDialog
showDialog(PROGRESS_DIALOG);
}
/* 执行那些很耗时的后台计算工作。可以调用publishProgress方法来更新实时的任务进度。 */
@Override
protected Integer doInBackground(ArrayList... datas) {
ArrayList data = datas[0];
for (int i=0; i<8; i++) {
data.add("ListItem");
}
return STATE_FINISH;
}
/* 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用, 后台的计算结果将通过该方法传递到UI thread.
* */
protected void onPostExecute(Integer result) {
int state = result.intValue();
switch(state){
case STATE_FINISH:
dismissDialog(PROGRESS_DIALOG);
Toast.makeText(getApplicationContext(), "加载完成!", Toast.LENGTH_LONG)
.show(); 。。。。。。
break;
case STATE_ERROR:
dismissDialog(PROGRESS_DIALOG);
Toast.makeText(getApplicationContext(), "处理过程发生错误!",Toast.LENGTH_LONG).show(); 。。。。。
break; default: }
}
public void handleMessage(Message msg) {//处理消息
text.setText(msg.obj.toString());
}
}
}