and中的Handler消息机制;
1:用来在各个线程之间传递信息;多用于子线程和主线程(UI)线程之间通信用;
2:该消息机制共有四部分:
Message:线程之间传递的消息;可以是基本类型数据,可以是引用型数据;
MessageQueue:线程所拥有的消息对列;用于存放接收到的消息;每个线程只能有一个消息对列;
Handler:就像是线程的一位看不见的魔术手,可以把其他线程的消息发往发送者Handler所在的线程的消息队列;
同时也可以处理其所在线程的消息队列中的消息;
发送消息使用sendMessage();处理消息则在handlerMessage()中进行;
Looper:是消息对列的管理者,会监控消息队列是否有未处理的消息,如果有的话则取出进行处理;
同时调用了Looper的loop()方法之后会进入一个无限循环中,持续性的监控消息队列的消息情况!
3:在主线程也就是UI线程中系统会自动创建对应的消息队列和消息循环,但是在子线程中必须手动创建消息队列和消息循环;
4:这种消息机制是为了在各个线程之间传递信息用的,因此各个部分都是以线程为基本单位的;
消息循环和消息队列的创建:
在子线程中:
1:调用Looper.prepare()来创建消息对列;
2:调用Looper.loop()进入消息循环;
3:完整的示例如下:
class WorkThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// 处理收到的消息
}
};
Looper.loop();
}
}
2:在主线程中则可以通过匿名内部类的形式:
public Handler handler = new Handler(){
public void handleMessage(Message msg) {
// 处理收到的消息
}
}:
3:消息的获取及处理:
通过handleMessage(Message msg) 获取消息队里中的消息,并在该方法内处理;
方式有:
public void handleMessage(Message msg) {
// 处理收到的消息
msg.what();
msg.obj();
msg.arg1();
msg.arg2();
msg.getData();
}
消息队列的发送:
消息的载体:Message:
Message: 用于传递消息体,内部携带少量信息,用于线程之间通信;
消息的创建:
Message message = new Message();
Messaeg message = handle.obtainMessage();
两种方式均能创建Message,但是第一种是直接创建对象,需要单独开辟空间;第二种则是从消息池中获取的数据;效率较高!
常用字段:
msg.what:用于存储信息;一般用what来携带识别码;其他方式发送数据;
识别码的作用就是为了能够在handleMessage()方法中识别不同线程发来的数据;
msg.arg1:携带一些基本类型的数据;
msg.arg2: 携带一些基本类型的数据;
msg.obj: 携带一个引用型数据;
msg.setData(Bundle bundle):携带Bundle类型的数据;
消息的发送:
public void send(){
handle.sendMessage();
}
AsyncTask的简单使用
1:AsyncTask是and封装出来的一个异步执行类;通过这个可以很简单的执行异步任务,然后根据需要更新UI;
不需要再创建子线程,通过消息循环实现异步任务的执行和更新;
2:AsyncTask是一个抽象类;其内部有以下几个方法,具体介绍如下;
public class MyAsyncTask extends AsyncTask<参数约束类型约束,进度显示单位类型约束,返回值类型约束>{
public MyAsyncTask(){
//初始化操作
}
public void onPreExecute(){
//在执行异步任务之前对界面的初始化操作,比如显示进度对话框等;
}
public Result doInBackground(T t){
//执行异步任务,在该方法中不可以更新UI;
}
public onProgressUpdate(Interger... in){
//该函数内主要用于对UI进行操作;
//当后台调用了publishProgress(Progress )方法;之后就会调用该方法,后台传递的数据就是上个方法的参数;
}
public onPostExecute(Result){
//当doInBackground()方法使用return返回值的时候该方法就会被调用;
//在该方法中可以获取到后台的返回值;然后对UI进行更新;
}
}
3:启动服务:new MyAsyncTask().execute(t);
实例:异步加载—imooc;