Android-AsyncTask

AsyncTask适用于在子线程中执行任务,然后在主线程中展示任务的执行进度以及执行结果的场景。

AsyncTask中封装了FutureTask线程任务,线程池和Handler。

AsyncTask不适合进行特别耗时的后台任务,对于特别耗时的后台任务,建议使用线程池。

创建AsyncTask

AsyncTask是一个抽象类,所以需要自定义一个继承自AsyncTask的类,然后创建自定义类的实例对象。
自定义类时,重写如下方法:

public abstract class AsyncTask<Params, Progress, Result>
	//自定义类在继承AsyncTask的时候,需要为Params,Progress,Result这三个泛型参数指定确定
		的类类型,Params表示执行线程任务时需要传入的参数的类型,通过AsyncTask的execute方法
		传入此类型参数,在doInBackground方法中执行线程任务时,使用此类型参数。
		Progress泛型表示在doInBackground方法中调用publishProgress方法更新进度时,
		publishProgress方法可以接受的进度值参数的类型,此类型的进度值在onPregressUpdate方法
		中使用。
		Result泛型表示执行完doInBackground方法中,返回的结果数据的类型,此类型的结果数据在
		onPostExecute方法中使用。
	//如果不需要使用到这三个泛型参数,那么用Void代替

@MainThread
protected void onPreExecute() {}
	//此方法在主线程中执行,并且是在调用线程池的execute方法执行线程任务之前执行,所以此方法
		是用来做一些准备工作的

@WorkerThread
protected abstract Result doInBackground(Params... params);
	//此方法在线程池内的子线程中执行,用来处理一个具体的线程任务,在此方法中调用publishProgress
		方法可更新任务执行的进度,调用publishProgress方法后会在主线程中回调onProgressUpdate
		方法。另外此方法需要返回一个任务执行完成后的结果数据对象,返回的结果数据对象会作为在
		主线程中的回调执行的onPostExecute方法的参数。

@MainThread
protected void onProgressUpdate(Progress... values) {}
	//此方法在主线程中执行,通过用于给UI显示参数进度值

@MainThread
protected void onPostExecute(Result result) {}
	//doInBackground方法在子线程中执行完成后,会在主线程中回调执行此方法,用于处理任务完成后的
		收尾工作。

@MainThread
protected void onCancelled() {}
	//当线程任务被取消后会执行此方法,如果线程任务被取消后,onPostExecute方法是不会被调用到的

通过AsyncTask执行线程任务

一个AsyncTask对象只能执行一次线程任务。
AsyncTask对象通过execute方法或executeOnExecutor方法来执行线程任务

@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
}

@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
        Params... params)

使用 AsyncTask 时的注意事项

  • AsyncTask对象必须在主线程中创建
  • AsyncTask对象的execute方法和executeOnExecutor方法必须在主线程中调用
  • 一个AsyncTask对象只能执行一次线程任务,即一个AsyncTask对象的execute方法或executeOnExecutor方法
    只能被开发者主动调用一次,否则会报异常。
  • onPreExecute、doInBackground、onProgressUpdate、onPostExecute、onCancelled这些方法都只是
    在AsyncTask内部被动回调的方法,开发者不能主动调用它们。
  • 在同一个进程中的所有调用execute方法执行线程任务的各个AsyncTask对象是串行执行任务的,即同一进程,
    同一时间,对于调用execute方法开始执行线程任务的所有AsyncTask对象的集合中,只有一个AsyncTask对象在
    执行线程任务。

调用了execute方法的所有AsyncTask对象在同一进程中串行执行任务的原理

public static final Executor THREAD_POOL_EXECUTOR;

public static final Executor SERIAL_EXECUTOR = new SerialExecutor();

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

private static class SerialExecutor implements Executor {
    final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
    Runnable mActive;

    public synchronized void execute(final Runnable r) {
        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);
        }
    }
}

@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
}

@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
        Params... params) {
    ...
    exec.execute(mFuture);

    return this;
}

如上,AsyncTask类中存在两个线程池变量SERIAL_EXECUTOR和THREAD_POOL_EXECUTOR,并且这两个线程池是
类相关的,即所有AsyncTask对象使用的都是同一个SERIAL_EXECUTOR线程池实例,和同一个
THREAD_POOL_EXECUTOR线程池实例。
SERIAL_EXECUTOR线程池只是用来把AsyncTask对象中的线程任务插入到ArrayDeque队列中,并且初始化线程
任务的执行,而THREAD_POOL_EXECUTOR线程池才是用来真正执行线程任务的。
从源码中可以看到,在把AsyncTask中的线程任务插入到队列的时候,还创建了一个Runnable对象对线程任务做
了包装处理,这个新建的Runnable对象的使用目的就是保证在一个线程任务执行完成后,再从队列中取出另一个
AsyncTask对象的线程任务放入THREAD_POOL_EXECUTOR线程池中接着执行。直到队列中没有其他AsyncTask的
线程任务。于是就做到了多个AsyncTask对象的线程任务在同一个进程中串行执行的效果。

如果想让多个AsyncTask对象的线程任务在同一个进程中并发执行,那么直接调用AsyncTask对象的
executeOnExecutor(Executor exec,Params... params)方法,传入THREAD_POOL_EXECUTOR线程池或
其他线程池即可。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值