线程- Android
杨杰 20131101
ANR
线程交互
Handler与消息处理
异步任务
总体介绍
ANR
Application Not Responding
ANR 产生原因
用户UI事件在5S内没有得到响应
广播接收在10内没有完成。。。
ANR
线程分类
1. Main Thread
负责界面绘制,更新,处理输入事件等
2. Worker Thread
ANR 解决
1. 主线程只负责UI交互和不耗时简单逻辑
2. 耗时操作必须在子线程完成
3. 子线程不应该接触UI操作,因为Android UI操作非线程安全
ANR
线程交互主要是指线程之间的通信和同步控制问题
异步线程一般基于消息通知机制去进行线程之间的流程控制
线程交互
实例代码
线程交互
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
doWork();
}
};
private void doWork() {
try {
(3000);
} catch (InterruptedException e) {
();
}
long id = ().getId();
String data = "I have done it, perfect";
String msg = "Sub thread id is: " + id + "\n" + data;
sendMsgToHandler(MSG_THREAD_WORK_COMPLETED, msg);
}
实例代码
线程交互
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
(msg);
Bundle bundle = ();
if ( == MSG_THREAD_WORK_COMPLETED) {
Object msgObject = (MESSAGE_TO_PASS);
String data = (String) msgObject;
refreshUI(data);
}
}
};
Android 消息循环
我们知道Windows是消息驱动的,并且有全局的消息循环系统。Google参考了Windows的消息循环机制,也在Android系统中实现了消息循环机制。
Android通过Looper、Handler来实现消息循环机制。Android的消息循环是针对线程的,每个线程都可以有自己的消息队列和消息循环。
Handler 与消息处理
消息循环和线程通信核心类
1. Handler
消息分发和接收器
2. Message
封装消息
3. MessageQueue
消息队列,装载消息,FIFO
4. Looper
维护消息队列,循环取消息
Handler 与消息处理
Android 线程通信
Android使用消息机制实现线程间的通信,线程通过Looper建立自己的消息循环,MessageQueue是FIFO的消息队列,Looper负责从MessageQueue中取出消息,并且分发到消息指定目标Handler对象。Handler对象绑定到线程的局部变量Looper,封装了发送消息和处理消息的接口。
Handler 与消息处理
什么是Handler
Handler 实际上是一个消息分发、接收的处理器
Handler主要用途
1. 指定计划Message在将来某个时间去执行
2. 线程间通信
在A线程上将指定消息发送到B线程消息队列,完成线 程通信
Handler 与消息处理
Looper被设计用来使一个普通线程变成Looper线程。所谓Looper线程就是循环工作的线程。
每个线程都可以成为Looper线程,主线程默认为Looper线程。
Looper线程负责循环从MessageQueue取出消息
Handler 与消息处理
Looper线程维护消息队列
Handler 与消息处理
Handler 和 Looper 关联
Handler 在和它关联的Looper线程拥有的消息队列上处理消息。
Handler 可以在任意线程中发送消息,消息总会被发送到Handler 所对应的 Looper 线程的消息队列上。
Handler 与消息处理
Handler 和 Looper 关联
Handler 与消息处理
子线程通知主线程UI更新机制
Handler 与消息处理
凡是通过 sub thread 去 dosth(), 做完后通知主线程这种方式就是典型的异步。也就是非阻塞的方式。
典型的阻塞方式
Socket socket …
(); (block)
之前所讲到的 Thread + Handler 方式 就是典型的异步。
异步任务
AsyncTask
1. 异步任务
2. 比 Thread + Handler 更加轻量级
针对Android系统特点进行定制和优化
3. 适合于简单的异步任务
只适用于简单,不是特别耗时的任务。如果非常耗时或者控制逻辑要求非常复杂,无法满足需求。
异步任务
API AsyncTask
1. AsyncTask(T1 params, T2 progress, T result )
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the background computation.
Result, the type of the result of the background computation.
2. protected Long doInBackground(。。。)
3. protected void onPostExecute(。。。)
异步任务
用法:
异步任务
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = ;
long totalSize = 0;
for (int i = 0; i < count; i++) {
//do sth …
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
用法
异步任务
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
说明
1. 一般只有需要和UI线程交互的短任务才使用 AsyncTask
2. AsyncTask 实例必须在UI thread 创建和启动
3. AsyncTask 实例任务只能执行一次
异步任务
Over
Q&A