本着深入浅出的原则,本文详细介绍了从线程到Handler消息传递机制的内容,中间多引用博客,如果不了解,还是要详细看下链接里面的内容,适合像我这种基础不扎实的同学学习下。
首先,废话下为什么要有异步任务:
如果在主线程(UI线程)操作一些耗时的操作容易造成卡顿,
Android 规定主线程中不可以做耗时操作(访问网络,操作数据库)
现在最基础的异步任务的使用方法:
1.使用Handler消息传递机制;
2.使用AsyncTask异步任务;
要是这时候你不熟悉实现多线程的方式,请狂点
java线程系列---Runnable和Thread的区别
结论:
实现方式是1.实现Runnable接口 2.继承Thread类
多线程肯定永远以实现Runnable接口为主
使用Runnable实现多线程可以达到资源共享目的
另外,Thread类也是Runnable亲儿子
要是这时候你不能随手写出Handler的实现方式,请狂点
Android Handler详细使用方法实例
用法:
1.将handler绑定到它所建立的线程中,简单粗暴没情趣
//使用handler时首先要创建一个handler(UI线程)
Handler handler = new Handler();
//将线程接口立刻送到线程队列中
handler.removeCallbacks(update_thread);
Runnable update_thread = new Runnable()
{
public void run()
{
//UI操作
}
};
handler.post(update_thread);
//将接口从线程队列中移除
2.handler的消息队列机制,慢条斯理前戏足
// 调用:
update_progress_handler.post(update_thread);
//创建一个handler,内部完成处理消息方法
Handler update_progress_handler = new Handler()
{
@Override
public void handleMessage(Message msg) {
// UI线程
// msg.arg1 = "bilibili"
}
};
Runnable update_thread = new Runnable()
{
public void run() {
Message msg = update_progress_handler.obtainMessage();
//把消息发送到消息队列中,msg对应handleMessage的入参
msg.arg1 = "bilibili";
update_progress_handler.sendMessage(msg);
}
};
//移除
update_progress_handler.removeCallbacks(update_thread);
3.自己看链接吧...
handler.sendMessage(msg) 和 handler.post(Runnable) 都知道什么情况下用了,接下来就是硬菜了
请狂点:
Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
结论
1、首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。
2、Looper.loop()会让当前线程进入一个无限循环,不端从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。
3、Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue想关联。
4、Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。
5、在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法
还有需要注意的,因为最终调用的方法都是这个
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
分发消息流程:
当Message的msg.callback不为空时,则回调方法msg.callback.run();
当Handler的mCallback不为空时,则回调方法mCallback.handleMessage(msg);
最后调用Handler自身的回调方法handleMessage(),该方法默认为空,Handler子类通过覆写该方法来完成具体的逻辑。
消息分发的优先级:
Message的回调方法:message.callback.run(),优先级最高;
Handler中Callback的回调方法:Handler.mCallback.handleMessage(msg),优先级仅次于1;
Handler的默认方法:Handler.handleMessage(msg),优先级最低。
对于很多情况下,消息分发后的处理方法是第3种情况,即Handler.handleMessage(),一般地往往通过覆写该方法从而实现自己的业务逻辑。
懵懵懂懂是嘛?换个方向给你说一遍,补充下内容,能更好的了解整个过程
Android消息机制的原理剖析—闭环总结
结论
(a)MessageQueue和Looper:一对一关系,MessageQueue的创建后放置在Looper中。
(b)Looper和线程:一个线程只有一个,创建之后保存在ThreadLocal中,想要获取ThreadLocal.get()即可。
(c)Handler和Looper:Handler创建时候,从ThreadLocal中获取Looper,Handler变量指向这个Looper,Handler和Looper绑定。
(d)Message和Handler:Handler发送Message时候,Message的target属性指向这个Handler,也是这个Handler来分发处理这个Message
(e)消息池:only one,所有线程共享。
现在Android的消息机制都玩的溜了,不过对于偶尔用到一次用到就要考虑什么异步消息处理机制,还要专门使用一个Handler来发送和接收消息,就好比每次哄好了好不容易脱光了衣服还要先洗澡一样...
这个时候,就必须要学会AsyncTask了
Android AsyncTask完全解析,带你从源码的角度彻底理解
强突:
* 执行次序 执行时机 方法名称 调用方
* 1 异步任务执行前 onPreExecute UI线程
* 2 异步任务执行中 doInBackground 后台线程
* 3 异步任务执行中 publishProgress 后台线程
* 4 异步任务执行中 onProgressUpdate UI线程
* 5 异步任务执行后 onPostExecute UI线程
使用:
private class MyTask extends AsyncTask<String, Integer, String> {
@Override
protected void onPreExecute() {
//onPreExecute方法用于在执行后台任务前做一些UI操作
}
//doInBackground方法内部执行后台任务,不可在此方法内修改UI
@Override
protected String doInBackground(String... params) {
//doInBackground方法内部执行后台任务,不可在此方法内修改UI
// 后台线程向UI线程发布进度状态
publishProgress(i);
return null;
}
@Override
protected void onProgressUpdate(Integer... progresses) {
//onProgressUpdate方法用于更新进度信息
}
@Override
protected void onPostExecute(String result) {
//onPostExecute方法用于在执行完后台任务后更新UI,显示结果
}
@Override
protected void onCancelled() {
//onCancelled方法用于在取消执行中的任务时更改UI
}
}
调用:
//注意每次需new一个实例,新建的任务只能执行一次,否则会出现异常
mTask = new MyTask();
mTask.execute();
//取消一个正在执行的任务,onCancelled方法将会被调用
mTask.cancel(true);
结论:
AsyncTask也是使用的异步消息处理机制,只是做了非常好的封装