AsyncTask 源码解析

作者: 北国雪WRG | 来源:发表于2019-02-18 19:18 被阅读5次

为了不同环境下的使用,Android对Thread进行了包装,产生了AsyncTask,HandleThread,IntentService。

1. AsyncTask

三个泛型Params用于初始化,Progress用于设置进度,Result返回的结果,如果没有参数则设置为Void

五个方法:

  1. onPreExecute(),任务执行之前操作
  2. doInbackground(Params),后台线程执行
  3. onProgressUpdate(Progress),任务执行过程中,主线程
  4. onPostExecute(),任务执行完成
  5. onCancelled(),取消任务

简单使用:

class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
 
    @Override
    protected void onPreExecute() {
        progressDialog.show();
    }
 
    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            while (true) {
                int downloadPercent = doDownload();
                publishProgress(downloadPercent);
                if (downloadPercent >= 100) {
                    break;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }
 
    @Override
    protected void onProgressUpdate(Integer... values) {
        progressDialog.setMessage("当前下载进度:" + values[0] + "%");
    }
 
    @Override
    protected void onPostExecute(Boolean result) {
        progressDialog.dismiss();
        if (result) {
            Toast.makeText(context, "下载成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show();
        }
    }
}

两个线程池:

  1. SerialExecutor :任务排队
  2. THREAD_POOL_EXECUTOR:执行任务

注意点:

  1. AsyncTask的类加载必须在主线程中完成,因为AsyncTask类中有静态域sHandler,用于切换主线程和子线程。sHnadler必须获取主线程的Looper,所以sHandler必须在主线程中创建。而静态变量的创建在类加载的时候完成,所以AsyncTask必须在主线程中加载。Android4.1之后系统自动完成这个操作。

  2. AsyncTask对象创建和execute方法必须在主线程中调用

    尝试在子线程中使用AsyncTask
    但是为啥呢?大都数帖子都说,因为sHandler必须在主线程中创建,但是sHandler为静态变量,在类加载的时候就创建了,而不是在对象生成的时候创建。这个解释是错误的。如果您知道为啥,还请指点一二。
  3. 一个AsyncTask只能被执行一次,不然会被报异常。查看源码,在执行 executor()方法之后,首先会检测AsyncTask的Status,如果 Status为RUNDING或者FINISHED则会抛出异常。在检测完Status之后将其设置为RUNNING

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)");
        }
    }
    mStatus = Status.RUNNING;
    onPreExecute();
    mWorker.mParams = params;
    exec.execute(mFuture);
    return this;
}
  1. Android3.0 之后AsyncTask任务由一个线程串行执行,如果是调用executeOnExecute则是并行执行任务。查看源码
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);// 执行任务
        }
    }
}

初始状态mActive为null,调用scheduleNext(),出队列让THREAD_POOL_EXECUTOR线程池去执行任务。r.run()执行完成之后运行finaly{}语句,调用下一个任务,依次继续。

参考资料

《Android艺术探索》
android中handler的一些总结以及使用(三)之HandleThread的使用

相关文章

  • Android AsyncTask 源码解析

    标签:Android AsyncTask 源码解析 1.关于AsyncTask 1.1 什么是AsyncTask?...

  • 4.AsyncTask使用,原理

    资料 AsyncTask处理机制详解及源码分析-工匠若水 AsyncTask 源码解析-鸿洋 带你认识不一样的As...

  • Android日记之AsyncTask源码解析

    前言 AsyncTask的使用方法请看Android日记之AsyncTask的基本使用,此篇的源码解析我们还是从使...

  • AsyncTask原理解析

    AsyncTask是一个串行的线程,本文主要通过源码解析它的原理 -->从 AsyncTask执行的方法execu...

  • AsyncTask 源码解析

    一、前言AsyncTask是一个异步任务。里面封装了线程池及Handler。所以,它可以方便地实现线程的切换及耗时...

  • AsyncTask源码解析

    参考资料:Android开发艺术探索 AsyncTask是一个Android官方提供的一种轻量级的异步任务类,它可...

  • AsyncTask源码解析

    AsyncTask 执行轻量级的异步任务,将结果传递给主线程,主线程根据结果更新UI. 使用 AsyncTask创...

  • AsyncTask源码解析

    AsyncTask源码解析 最近再刷一些基础的东西,所以就随便记录了一些看源码的心得,目前开发中见到了很多Asyn...

  • AsyncTask源码解析

    参考资料 鸿洋版AsyncTask郭霖版AsyncTask线程池Android开发艺术探索Android源码 相关...

  • AsyncTask源码解析

    变量 1. CPU_COUNT CPU总数 2. CORE_POOL_SIZE 核心线程数 3.MAXIMUM...

网友评论

    本文标题:AsyncTask 源码解析

    本文链接:https://www.haomeiwen.com/subject/iarzeqtx.html