相关文章:
【多线程】一、线程状态切换
【多线程】二、线程优先级&守护线程
【多线程】三、线程访问变量
【多线程】四、线程异常抓捕
【多线程】五、线程池
【多线程】六、锁与同步
【多线程】七、阻塞队列
【多线程】八、异步计算结果获取
【多线程】九、Android异步任务
Handler机制解析
相关 | 用途 | 说明 |
---|---|---|
MessageQueue | 消息队列容器 | 单链表实现 (1) enqueueMessage :添加消息必要时唤醒next (2) next :读取消息,无消息时阻塞 |
Looper | 消息循环读取器 | (1)Looper.prepare() :创建MessageQueue (2) Looper.loop() :启动无限循环调MessageQueue.next() 若返回 null 退出;非null 则调Message#target.dispatchMessage() |
Handler | 消息发送和处理器 | (1)发送:Handler#post Hanlder#sendMessage Looper::myLooper().messageQueue#enqueueMessage ;(2)处理: Hanlder#dispatchMessage Message#callback Hanlder#Callback#handleMessage Handler#handleMessage |
ThreadLocal | 保障Looper互不干扰 | 线程全局变量,原理似HashMap<Thread,T> |
消息处理示例
private volatile Handler mHandler;
private Handler.Callback mCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.e(TAG, "handleMessage: " + Thread.currentThread());
// 执行完毕退出loop循环,销毁Thread
if(null != Looper.myLooper()){
Looper.myLooper().quitSafely();
}
// Looper#quit 方法会立即退出,quitSafely会在消息处理完毕后退出;
// Looper退出后,Handler#send返回false发送消息失败;
return true;
}
};
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
Looper.prepare();
// Handler在哪个线程创建就在哪个线程处理
mHandler = new Handler(mCallback);
Looper.loop();
}
};
// =============== 切线程示例 ===============
// 创建处理线程
new Thread(mRunnable, "Thread-0").start();
// 在其他线程发起消息
new Thread(new Runnable() {
@Override
public void run() {
// 切到Thread-0
mHandler.sendEmptyMessage(0x00);
}
},"Thread-1").start();
View单线程模型
为保证View状态和操作简单保障性能,ViewRoomImpl会checkThread
,以保证在主线程操作UI(ActivityThread#main:Looper.prepareMainLooper
)
主线程Looper
AMS中的回调运行在Binder线程池,通过ActivityThread#H
切换到主线程处理各组件生命周期;主线程Looper
初始化过程见ActivityThread::main
执行异步任务的方式
方式 | 使用 | 说明 |
---|---|---|
AsyncTask | 串行启动:task.execute(param1,param2) 并行启动: task.executeOnExecutor(params) | 适用轻量级异步任务,便于更新UI 一个AsyncTask对象只能调用execute一次 多个Task在1.6之前和3.0之后默认串行执行 |
HandlerThread | (1)异步Handler: 创建HanlderThread并 start 用它的 Looper 创建Handler 使用完毕后 HandlerThread#quit (2)IntentService Android在 IntentService#OnCreate 中创建了 HanlderThread 并start 了; | 具有Looper的Thread 注意 start(Looper#loop) 是阻塞的需手动quit |
IntentService | Context#startService(Intent) | 适用高优先级需报活的耗时任务 能自动退出,比 Thread 更易保活; |
Executor | execute() ,submit() | 复用Thread 对象, 减少线程建销成本 |
AsyncTask解析
class AsyncTask<Params,Progress,Result>{
// 主线程,准备执行;
onPreExecute();
// 工作线程池 AsyncTask::SERIAL_EXECUTOR/THREAD_POOL_EXECUTOR
doInBackground(Params...params);
// 主线程,进度已更新;
onProgressUpdate(Progress...progress);
// 主线程,任务完成;
onPostExecute(Result result)
// 主线程,任务取消;
onCancelled();
// 通知进度更新
publishProgress();
// 查询是否被外部取消
isCancelled();
}
工作流程:
AsyncTask#execute
-> AsyncTask#executeOnExecutor
-> SerialExecutor#execute-> ThreadPoolExecutor#execute
-> FutureTask#run -> WorkerRunnable#call
-> AsyncTask#doInBackground -> AsyncTask#postResult
-> InternalHandler#handleMessage -> AsyncTask#finish
-> AsyncTask#onPostExecute / onCancelled
IntentService解析
注:
- stopSelf(startId): 如果所有任务执行完毕(laststartId==startId?)则退出(当startId=-1立即退出);
- 由于Looper是串行处理消息,所以一个IntentService的多个Intent任务也是串行处理的;