`

AsyncTask实现原理和内部代码[转]

 
阅读更多

AsyncTask实现原理和内部代码

作者: Android开发网原创 时间: 2011-04-15

  Android从1.5开始引入了AsyncTask这个类,可以帮助我们解决线程和界面刷新问题,主要是对Thread+Handler这样的封装,但在设计模式和代码维护方面都有不错的表现。对于AsyncTask的实现原理和内部的代码如何实现Android123一起和大家分享,早在2008年时Google推出了一个示例应用叫PhotoStream来演示UI在多线程网络慢速I/O下的刷新问题,里面的线程构造使用的正是AsyncTask的雏形,由于内部使用Java 1.5的并发库比普通初级Android开发者编写的Thread+Handler稳定很多,下面我们就android.os.AsyncTask的实现

  public abstract class AsyncTask<Params, Progress, Result> {
    private static final String LOG_TAG = "AsyncTask";

    private static final int CORE_POOL_SIZE = 5; //线程池数量
    private static final int MAXIMUM_POOL_SIZE = 128; //线程池中最大线程数
    private static final int KEEP_ALIVE = 1;

    private static final BlockingQueue<Runnable> sWorkQueue =
            new LinkedBlockingQueue<Runnable>(10); //使用并发库的阻塞队列初始时保存10个Runnable对象

    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };

    private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
            MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); //创建线程池

    private static final int MESSAGE_POST_RESULT = 0x1; 
    private static final int MESSAGE_POST_PROGRESS = 0x2;
    private static final int MESSAGE_POST_CANCEL = 0x3;

    private static final InternalHandler sHandler = new InternalHandler(); //这个是对Handler的封装,内部处理Thread的状态。

    private final WorkerRunnable<Params, Result> mWorker;  //该类对Runnable做简单封装
    private final FutureTask<Result> mFuture; //对于并发库而言FutureTask是最重要的,有兴趣的网友可以看下JDK源码

    private volatile Status mStatus = Status.PENDING; //保存当前线程状态

    public enum Status { //枚举类记录当前线程状态
        PENDING,
        RUNNING,
        FINISHED,
    }

    public AsyncTask() {
        mWorker = new WorkerRunnable<Params, Result>() { //构造Runable对象
            public Result call() throws Exception {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //设置线程优先级为后台,这里Android开发网提示大家低于标准线程优先级
                return doInBackground(mParams);
            }
        };

        mFuture = new FutureTask<Result>(mWorker) { 
            @Override
            protected void done() {
                Message message;
                Result result = null;

                try {
                    result = get();
                } catch (InterruptedException e) { //处理Thread中断异常
                    android.util.Log.w(LOG_TAG, e);
                } catch (ExecutionException e) {
                    throw new RuntimeException("An error occured while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
                            new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null)); 

                    message.sendToTarget();
                    return;
                } catch (Throwable t) {
                    throw new RuntimeException("An error occured while executing "
                            + "doInBackground()", t);
                }

                message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
                        new AsyncTaskResult<Result>(AsyncTask.this, result)); //执行完后通过Handler通知结果
                message.sendToTarget();
            }
        };
    }

    public final Status getStatus() {
        return mStatus;
    }

    protected abstract Result doInBackground(Params... params);

    protected void onPreExecute() {
    }

    protected void onPostExecute(Result result) {
    }

    protected void onProgressUpdate(Progress... values) {
    }

    protected void onCancelled() {
    }

    public final boolean isCancelled() {
        return mFuture.isCancelled();
    }

    public final boolean cancel(boolean mayInterruptIfRunning) {
        return mFuture.cancel(mayInterruptIfRunning);
    }

    public final Result get() throws InterruptedException, ExecutionException {
        return mFuture.get();
    }

    public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
            ExecutionException, TimeoutException {
        return mFuture.get(timeout, unit);
    }

    public final AsyncTask<Params, Progress, Result> execute(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;
        sExecutor.execute(mFuture);

        return this;
    }

    protected final void publishProgress(Progress... values) { //通过Handler通知UI刷新
        sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
                new AsyncTaskResult<Progress>(this, values)).sendToTarget();
    }

    private void finish(Result result) {
        if (isCancelled()) result = null;
        onPostExecute(result);
        mStatus = Status.FINISHED;
    }

    private static class InternalHandler extends Handler { //和我们的Handler没有什么不同
        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
        @Override
        public void handleMessage(Message msg) {
            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
            switch (msg.what) {
                case MESSAGE_POST_RESULT:
                    // There is only one result
                    result.mTask.finish(result.mData[0]);
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);
                    break;
                case MESSAGE_POST_CANCEL:
                    result.mTask.onCancelled();
                    break;
            }
        }
    }

    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
        Params[] mParams;
    }

    @SuppressWarnings({"RawUseOfParameterizedType"})
    private static class AsyncTaskResult<Data> {
        final AsyncTask mTask;
        final Data[] mData;

        AsyncTaskResult(AsyncTask task, Data... data) {
            mTask = task;
            mData = data;
        }
    }
}

 经过上面的简单分析相信大家对Android AsyncTask会有更加深刻的理解,整个AsyncTask实现基于Thread+Handler,但对于Thread使用的是Java的并发包的FutureTask具体的可以参考JDK5以后的源码。

分享到:
评论

相关推荐

    Android AsyncTask 源码解析

    在深入探讨 AsyncTask 的源码之前,我们首先需要理解它的基本用法和工作原理。 ### 1. AsyncTask 的基本使用 AsyncTask 通常包含三个泛型参数:`Params`(输入参数类型)、`Progress`(后台执行过程中的进度类型)...

    Android AsyncTask Demo 自己参考网络写的学习 demo

    这个“Android AsyncTask Demo”是开发者为了学习和理解AsyncTask工作原理而编写的示例代码。下面我们将深入探讨AsyncTask的相关知识点。 1. **AsyncTask简介** AsyncTask是Android提供的一个轻量级组件,它允许...

    AsyncTask 源码解析

    本文将深入探讨 AsyncTask 的内部实现原理、工作流程以及关键代码分析。 首先,AsyncTask 有三个泛型参数,分别代表输入参数类型(Params)、进度更新参数类型(Progress)和结果参数类型(Result)。通过这些参数...

    使用AsyncTask提高android线程的效率

    1. **代码结构**:建议将`AsyncTask`作为内部类,使其与使用它的Activity或Fragment紧密结合,方便管理。 2. **错误处理**:确保在`doInBackground()`中捕获异常,避免崩溃,并在`onPostExecute()`中处理异常情况。 ...

    异步AsyncTask状态监控

    本教程将深入讲解AsyncTask的工作原理、如何创建和使用,以及如何实现对异步任务状态的监控,特别是关注任务的结束状态。 AsyncTask的核心理念是“后台计算,前台显示”,它提供了三个泛型参数:Params, Progress, ...

    android AsyncTask详细介绍

    在Android开发中,异步处理是非常关键的一部分,它允许开发者在不阻塞用户界面的情况下执行耗时的操作。...在实际开发中,理解它们的工作原理和应用场景,能够帮助我们编写出更加高效和易维护的代码。

    模范Android中的AsyncTask

    - `javaLooper`这个文件名可能表示该压缩包包含与`Looper`和`Handler`相关的代码示例或解释,这可以帮助我们更好地理解如何在`AsyncTask`中利用这两个组件。 5. **替代方案** - 自Android 3.0(API级别11)起,...

    异步任务Asynctask源码与反编译对比

    在Android开发中,异步任务(AsyncTask)是一种常见的用于执行后台操作的工具,...通过对比源码与反编译代码,我们可以深入了解Android系统如何调度和管理任务,这对于解决相关问题和实现高效的应用程序设计至关重要。

    Android-详细解读AsyncTask的黑暗面以及一种替代方案

    在深入探讨AsyncTask的“黑暗面”之前,我们先来回顾一下AsyncTask的基本用法和工作原理。 AsyncTask主要由四个关键部分组成:onPreExecute()、doInBackground()、onProgressUpdate()和onPostExecute()。其中,...

    Android中AsyncTask的入门使用学习指南

    - **内存泄漏**:如果Activity持有AsyncTask的引用,而AsyncTask内部又持有Activity的引用,会导致Activity无法正常销毁,从而引发内存泄漏。解决方法是在不需要时取消任务或使用弱引用。 - **序列化执行**:默认...

    android AsyncTask

    在阅读给定的博客链接()时,你可以深入理解AsyncTask的实现细节和最佳实践。博客可能涵盖了AsyncTask的源码分析,如何避免内存泄漏,以及如何正确取消AsyncTask等主题。通过深入学习,你可以更好地掌握如何在实际...

    Android 使用AsyncTask实现多线程断点续传

    ### 一、实现原理 1. **确定下载线程范围**: 多线程下载的关键在于将大文件分成多个小块,每个线程负责下载其中一块。例如,如果设定默认下载线程数为5,可以计算每个线程的起始和结束位置。例如,通过`block...

    AsyncTasky研究

    `AsyncTask`内部通过线程池管理后台线程,以及利用`Handler`机制实现主线程与后台线程间的通信。具体来说,`AsyncTask`定义了三个泛型参数: - **Params**:用于启动任务执行的输入参数,例如HTTP请求的URL。 - **...

    简介Android 中的AsyncTask

    首先,AsyncTask的工作原理是通过内部创建一个新的线程来执行`doInBackground()`方法,这个方法用于执行非UI相关的计算或网络操作。完成后,结果会被传递给`onPostExecute()`方法,该方法运行在主线程,适合更新UI。...

    Android Volley,AsyncTask,FinalHttp 请求对比内存泄漏

    在Android应用开发中,网络请求是常见的操作,开发者通常会使用不同的库来实现这一功能,如Volley、AsyncTask和FinalHttp。本文将深入探讨这三个工具在网络请求中的使用,以及它们与内存泄漏的关系,特别是针对...

    Android ndroid 查询工具源代码.zip

    本篇将针对"Android ndroid 查询工具源代码.zip"进行深入剖析,探讨其核心功能与实现原理。 源代码是软件开发的基础,对于Android查询工具而言,源代码揭示了其内部的工作机制。此压缩包中的"Android ndroid 查询...

    Android应用程序开发源代码

    在Android应用程序开发中,源代码是开发者的心血结晶,它揭示了应用的工作原理和实现细节。密西西比河谷州立大学提供的这个"Android应用程序开发源代码"资源,无疑为学习者提供了一个宝贵的实践平台,能够加深对...

    第一行代码Android学习练习代码10

    练习中,你将学习如何在Service内部创建线程,如使用Handler、AsyncTask或者Thread类,以实现后台任务的异步执行。同时,你还将了解如何在服务中更新UI,这通常需要用到Handler的post或者Looper机制,确保UI更新在...

    Android大图加载示例代码和apk

    在Android开发中,大图加载是一项重要...这个示例代码和apk可以帮助开发者学习和实践上述技术,通过实际操作理解大图加载的原理和最佳实践。通过分析和运行代码,可以进一步掌握Android大图加载的技巧,提升开发能力。

Global site tag (gtag.js) - Google Analytics