AsyncTask

本文深入剖析AsyncTask机制,探讨其在Android应用中实现异步任务的关键作用。从基础使用到内部原理,包括线程池配置、任务执行流程及消息处理机制,帮助开发者掌握AsyncTask的高效运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AsyncTask

应用场景:需获取子线程耗时任务的回调结果。需在Thread和Handler中编写代码逻辑,AsyncTask类将两者封装统一,相当于多线程框架

基础使用

1、以下重写的方法除doInBackground(),均在主线程中执行
2、AsyncTask的实例必须在主线程中创建,execute()必须在主线程中调用
3、一个AsyncTack的实例,只能执行一次execute方法,否则抛出异常

class MyTask extends AsyncTask<String,Object,Long>{
    //泛型参数分别为传入参数类型,返回给UI线程的进度参数类型,结果参数类型
    @Override protected void onPreExecute(){
        super.onPreExecute();
    }
    @Override protected Long doInBackground(String... params){
        return null;
    }
    @Override protected void onProgressUpdate(Object... values){
        super.onProgressUpdate(values);
    }
    @Override protected void onPostExecute(Long s){
        super.onPostExecute(s);
    }
    @Override protected void onCancelled(Long s){
        super.onCancelled(s);
    }
}
//execute(),executeOnExecutor()传入的参数对应的泛型为传入参数,因此类型要一致
//单一后台线程串行执行
new MyTask().execute(urls);	
//多线程并行执行
new MyTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, urls);
//取消
AsyncTask.cancel();

AsyncTask机制的原理

本质为一个静态的线程池,任务都是提交到此线程池中执行
线程池中的工作线程执行 doInBackground(mParams)方法执行异步的任务
任务状态改变后,工作线程向UI线程发送消息,AsyncTask内部的InternalHandler响应这些消息,并调用相关的回调函数

execute:单个线程,对应线程池Executors.newSingleThreadPool

executeOnExecutor:多个线程,可自定义线程池。执行无数个,即用java线程池的Executors.newCachedThreadPool,AsyncTask默认线程池为Executors.newFixedThreadPool,最多5个。

注意事项

内存泄漏
解决方法:让内部持有外部的弱引用即可解决
生命周期
在Activity的onDestory()中及时对AsyncTask进行回收,调用其cancel()方法来保证程序的稳定性
结果丢失
当内存不足时,当前的Activity被回收,由于AsyncTask持有的是回收之前Activity的引用,导致AsyncTask更新的结果对象为一个无效的Activity的引用,这就是结果丢失
并行或串行
1.6(Donut)之前:任务串行。多个AsyncTask处理结果作用于UI视图会产生问题
1.6-3.0:任务并行。如果其中一条任务执行出现问题,会引起其他任务出现错误
3.0:顺序执行,并添加executeOnExecutor()用于并行

源码解析

//必须在UI主线程中调用该方法。
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
	return executeOnExecutor(sDefaultExecutor, params);
}
//跳转到executeOnExecutor方法
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
		Params... params) {
	if (mStatus != Status.PENDING) {
		switch (mStatus) {
			case RUNNING:
				throw new IllegalStateException("Cannot execute task:"
						+ " the task is already running.");
			case FINISHED:
				throw new IllegalStateException("Cannot execute task:"
						+ " the task has already been executed "
						+ "(a task can be executed only once)");
		}
	}
   //设置当前AsyncTask的状态为RUNNING
	mStatus = Status.RUNNING;
	//还是在UI主线程,这个时候可以进行一些初始化操作
	onPreExecute();
	mWorker.mParams = params;
	exec.execute(mFuture);
	return this;
}

mWork变量

private final WorkerRunnable<Params, Result> mWorker;
//Callable的子类,且包含一个mParams用于保存传入的参数
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
        Params[] mParams;
}
//mWork初始化在AsyncTask的构造函数中进行的
mWorker = new WorkerRunnable<Params, Result>() {
	public Result call() throws Exception {
		//设置为true,下面要用到
		mTaskInvoked.set(true);
		Result result = null;
		try {
			Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
			//获取处理结果
			result = doInBackground(mParams);
			Binder.flushPendingCommands();
		} catch (Throwable tr) {
			mCancelled.set(true);
			throw tr;
		} finally {
			//发送执行结果
			postResult(result);
		}
		return result;
	}
};
//postResult方法
private Result postResult(Result result) {
    @SuppressWarnings("unchecked")
    Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
		new AyncTaskResult<Result>(this, result));
    //通过Hanlder发送消息
    message.sendToTarget();
    return result;
}
//找到相应的Hanlder
private static Handler getHandler() {
    synchronized (AsyncTask.class) {
        if (sHandler == null) {
            sHandler = new InternalHandler();
        }
        return sHandler;
    }
}
//消息处理
private static class InternalHandler extends Handler {
	public InternalHandler() {
		super(Looper.getMainLooper());
	}
	@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
	@Override
	public void handleMessage(Message msg) {
		AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
		switch (msg.what) {
			case MESSAGE_POST_RESULT:
				result.mTask.finish(result.mData[0]);
				break;
			case MESSAGE_POST_PROGRESS:
				result.mTask.onProgressUpdate(result.mData);
				break;
		}
	}
}
//消息处理完之后,设定状态为finished
private void finish(Result result) {
	if (isCancelled()) {
		onCancelled(result);
	} else {
		//执行4个方法中的最后一步,处理结果
		onPostExecute(result);
	}
	//设置最后的状态为结束finished
	mStatus = Status.FINISHED;
}

mFuture变量

//申明变量
private final FutureTask<Result> mFuture;
//在AsyncTask的构造函数中进行变量的初始化
mFuture = new FutureTask<Result>(mWorker) {
	@Override
	protected void done() {
		try {
			postResultIfNotInvoked(get());
		} catch (InterruptedException e) {
			android.util.Log.w(LOG_TAG, e);
		} catch (ExecutionException e) {
			throw new RuntimeException("An error occurred while executing doInBackground()",
					e.getCause());
		} catch (CancellationException e) {
			postResultIfNotInvoked(null);
		}
	}
};
//查看postResultIfNotInvoked方法,参数是get(),get()表示获取mWorker的call的返回值,即Result
private void postResultIfNotInvoked(Result result) {
    //mWork初始化时设置的变量值mTaskInvoked.set(true),所以判断中一般都是wasTaskInvoked=true,所以基本不会执行
	final boolean wasTaskInvoked = mTaskInvoked.get();
	if (!wasTaskInvoked) {
		postResult(result);
	}
}

exec.execute(mFuture);

//线程池sDefaultExecutor的定义,即上述的exec
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
//继续跟踪SERIAL_EXECUTOR
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
//SerialExecutor的定义
private static class SerialExecutor implements Executor {
	//维护一个数组队列
	final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
	Runnable mActive;
	//执行内容
	public synchronized void execute(final Runnable r) {
		//在队列的尾部插入一个任务task
		mTasks.offer(new Runnable() {
			public void run() {
				try {
					r.run();
				} finally {
					scheduleNext();
				}
			}
		});
		if (mActive == null) {
			scheduleNext();
		}
	}
	protected synchronized void scheduleNext() {
		//取出队首的任务开始执行
		if ((mActive = mTasks.poll()) != null) {
			//开始执行任务
			THREAD_POOL_EXECUTOR.execute(mActive);
		}
	}
}
//THREAD_POOL_EXECUTOR
public static final Executor THREAD_POOL_EXECUTOR;
//线程池配置
static {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
        CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
        sPoolWorkQueue, sThreadFactory);
    threadPoolExecutor.allowCoreThreadTimeOut(true);
    THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
//变量设置
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// We want at least 2 threads and at most 4 threads in the core pool,
// preferring to have 1 less than the CPU count to avoid saturating
// the CPU with background work
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE_SECONDS = 30;

总结

1、在UI线程,设置当前AsyncTask的状态为RUNNING,然后执行了onPreExecute()
2、将传入的参数赋值给了mWorker.mParams。mWorker为一个Callable的子类,且在内部的call()方法中,调用了doInBackground(mParams),然后得到的返回值作为postResult的参数进行执行。postResult中通过sHandler发送消息,最终sHandler的handleMessage中完成**onPostExecute()**的调用
3、最后执行exec.execute(mFuture),mFuture为真正的执行任务的单元,将mWorker进行封装,然后由sDefaultExecutor交给线程池进行执行

onProgressUpdate()的调用时机

//使用AsyncTask中的第三个方法doInBackground时在里面我们调用了一个传递进度的方法 publishProgress(int progress)
@WorkerThread
//其实就是发送一个消息
protected final void publishProgress(Progress... values) {
    if (!isCancelled()) {
        //通过Handler和Message异步消息机制进行UI线程和Work线程通信
        //消息类型 msg.what=MESSAGE_POST_PROGRESS
        //进度	msg.obj=new AsyncTaskResult<Progress>(this, values)
        getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                                   new AsyncTaskResult<Progress>(this, values)).sendToTarget();
    }
}
//处理消息
private static class InternalHandler extends Handler {
    public InternalHandler() {
        super(Looper.getMainLooper());
    }
    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
        AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
        switch (msg.what) {
            case MESSAGE_POST_RESULT:
                result.mTask.finish(result.mData[0]);
                break;
            case MESSAGE_POST_PROGRESS:	//处理进度消息
                //调用onProgressUpdate方法显示进度
                result.mTask.onProgressUpdate(result.mData);
                break;
        }
    }
}

AsyncTask内部线程池

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
sDefaultExecutor是SerialExecutor的一个实例,而且它是个静态变量。
一个进程里面所有AsyncTask对象都共享同一个SerialExecutor对象

深入解析AsyncTask

待更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值