【多线程】九、Android异步任务

相关文章:
【多线程】一、线程状态切换
【多线程】二、线程优先级&守护线程
【多线程】三、线程访问变量
【多线程】四、线程异常抓捕
【多线程】五、线程池
【多线程】六、锁与同步
【多线程】七、阻塞队列
【多线程】八、异步计算结果获取
【多线程】九、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
中创建了HanlderThreadstart了;
具有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解析

Created with Raphaël 2.2.0ContextImpl#startService已创建?onStartCoommondonStart(已调stopSelf)onHandleIntent(Intent)stopSelf(startId)AMS#stopServiceTokenActiveServices#stopServiceTokenLockedonDestroyHandlerThread#quitonCreateyesno

注:

  1. stopSelf(startId): 如果所有任务执行完毕(laststartId==startId?)则退出(当startId=-1立即退出);
  2. 由于Looper是串行处理消息,所以一个IntentService的多个Intent任务也是串行处理的;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章