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

20 篇文章 0 订阅

相关文章:
【多线程】一、线程状态切换
【多线程】二、线程优先级&守护线程
【多线程】三、线程访问变量
【多线程】四、线程异常抓捕
【多线程】五、线程池
【多线程】六、锁与同步
【多线程】七、阻塞队列
【多线程】八、异步计算结果获取
【多线程】九、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
IntentServiceContext#startService(Intent)适用高优先级需报活的耗时任务
能自动退出,比Thread更易保活;
Executorexecute(),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.0 ContextImpl#startService 已创建? onStartCoommond onStart(已调stopSelf) onHandleIntent(Intent) stopSelf(startId) AMS#stopServiceToken ActiveServices#stopServiceTokenLocked onDestroy HandlerThread#quit onCreate yes no

注:

  1. stopSelf(startId): 如果所有任务执行完毕(laststartId==startId?)则退出(当startId=-1立即退出);
  2. 由于Looper是串行处理消息,所以一个IntentService的多个Intent任务也是串行处理的;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值