`
寻梦者
  • 浏览: 638183 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

android的AsyncTask源码分析

 
阅读更多

一说到AsyncTask,大家就会说 ,他是系统提供给我的用于执行异步任务的工具类。比Handler好用只需要重写方法,每个Asynchronous对象只能执行1次。但是他必须要放在主线程里创建。为什么呢?这都是为什么呢?我们就来对这些疑惑一探究竟:

         打开这个类,我喜欢只有除去一些注释只有250多行:

   二话不说,先看他的构造吧:

     public AsyncTask() {

        mWorker = new WorkerRunnable<Params, Result>() {

            public Result call() throws Exception {

                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

                return doInBackground(mParams);//调用了doInBackground

            }

        };//构建了一个mWorkà WorkerRunnable是具有prams参数的一个抽象类,实现了Callable接口。

        mFuture = new FutureTask<Result>(mWorker) {//mWorker创建了FutureTask

            @Override// FutureTask(Runnable runnable, V result)

//FutureTask通过一个Runnable/Callable构造,一旦运行完成通过get();返回一个Result

            protected void done() {

                Message message;

                Result result = null;

                try {

                    result = get();//获得mWork返回的Result

                } catch (InterruptedException e) {

                    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));

                  // sHandler是自己的HandlerobtainMessage:通过whatobj获得msg

                                     //实际调用: Message.obtain(this, what, obj);得到1MSg

                    message.sendToTarget();//target.send(msg)发送了一个消息给自觉封装好的Handler

                    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));

                message.sendToTarget();

            }

        };

    }

    这时调用了HandleMessage()方法,下面是那个Handler的具体代码:

         private static class InternalHandler extends Handler {

        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})

        @Override//看到了吧,我们要重写的几个方法。他们现在都是空实现。

        public void handleMessage(Message msg) {

            AsyncTaskResult result = (AsyncTaskResult) msg.obj;//取得消息里的Result

            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;

            }

        }

    }

 

这里涉及到一个AsyncTaskResult result和:

private static class AsyncTaskResult<Data> {//创建分派消息时,将Result封装为AsyncTaskResult

        final AsyncTask mTask;//封装1个异步任务,创建消息时this

        final Data[] mData;//我们创建消息时mData:为Result

        AsyncTaskResult(AsyncTask task, Data... data) {

            mTask = task;

            mData = data;

        }

    }

哪为什么要在Ui线程实例化呢,:

         因为他的本质还是HandlerHandler对象与当前线程关联,也就说,我们想通过异步分离UI和后台处理,当然要在Ui实例化。

         为什么又只能执行1次呢:

我们看,通过代码的结构:我们要通过execute执行(为什么?)来传递我们要执行的参数:

他内部定义了一个状态并初始化为PENGDING

private volatile Status mStatus = Status.PENDING;

       public enum Status {PENDING, RUNNING, FINISHED, }

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;//只能在这里修改1次,这就是执行1次的原因.

        onPreExecute();//如果定义了onPreExecute(),则执行,否则空实现;

        mWorker.mParams = params;//初始化mWorker的参数

        sExecutor.execute(mFuture);//这是执行FutureTask的方式。回到了我上面的讲解。

        return this;

    }

         这里也顺便讲一下Progress的更新吧:

                   protected final void publishProgress(Progress... values) {

        sHandler.obtainMessage(MESSAGE_POST_PROGRESS,

                new AsyncTaskResult<Progress>(this, values)).sendToTarget();

    }

这下,你是不是明白呢!

分享到:
评论

相关推荐

    Android AsyncTask 源码解析

    **Android AsyncTask 源码解析** AsyncTask 是 Android 平台上一个非常重要的工具类,用于在后台线程执行耗时操作,然后在 UI 线程更新结果,从而避免了因长时间运行任务而导致的 ANR(Application Not Responding...

    Android AsyncTask源码分析

    Android的AsyncTask是一个轻量级的异步任务框架,它被设计用来简化在主线程与后台线程之间进行数据交互的复杂性。由于Android的UI更新必须在主线程中进行,AsyncTask通过内部封装Handler和线程池,使得开发者可以在...

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

    在Android开发中,AsyncTask是一种常用的工具类,用于在后台线程执行耗时操作,同时在UI线程更新进度或结果。这个“Android AsyncTask Demo”是开发者为了学习和理解AsyncTask工作原理而编写的示例代码。下面我们将...

    Android开发之AsyncTask机制及使用细节例子源码

    在Android应用开发中,异步任务(AsyncTask)是一个常用工具,用于在后台线程执行耗时操作,然后在UI线程...通过分析这个示例,开发者可以更好地理解和掌握AsyncTask的工作原理,以便在自己的项目中有效利用这一工具。

    AsyncTask 源码解析

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

    Android_上百实例源码分析以及开源分析_集合打包4

    此外,源码分析还包括对Android框架组件的理解,如Intent、Fragment、Loader、AsyncTask等,这些是构建复杂应用的基础。 二、集合类的深入理解和优化 在Android开发中,集合类(如ArrayList、LinkedList、HashMap...

    android AsyncTask

    博客可能涵盖了AsyncTask的源码分析,如何避免内存泄漏,以及如何正确取消AsyncTask等主题。通过深入学习,你可以更好地掌握如何在实际项目中有效地使用AsyncTask。 在提供的"testAsync"文件中,可能包含了一些示例...

    Android代码-Android 一些重要知识点解析整理

    Android中AsyncTak的使用与源码分析 Android AsyncTask 完全解析,带你从源码的角度彻底理解 Android 异步消息处理机制完全解析,带你从源码角度彻底理解 Android 异步消息处理机制 让你深入理解 Looper、...

    Android应用源码之AsyncTask_Download1)_源码.zip

    这个源码示例“Android应用源码之AsyncTask_Download1)”很可能是一个简单的下载任务实现,利用了AsyncTask来处理网络下载。让我们深入探讨AsyncTask及其在Android中的使用。 AsyncTask是Android提供的一个轻量级...

    Android Socket源码实现与PC通讯

    本文将深入探讨Android Socket源码实现与PC通讯的核心概念、步骤以及具体Java源码解析。 Socket,也被称为套接字,是网络编程中的基本组件,它提供了进程间通信(IPC,Inter-Process Communication)的能力,尤其...

    新浪微博Android客户端源码

    在源码分析中,开发者可以关注以下几个关键知识点: 1. **应用架构**:学习模块化设计,例如MVVM(Model-View-ViewModel)或MVP(Model-View-Presenter)架构,以及如何组织各个组件和模块。 2. **网络通信**:...

    Android经典源码全集

    10. **性能优化**:源码可能涵盖内存优化、CPU优化、启动速度优化等方面,如使用ProGuard和R8进行代码混淆,使用LeakCanary检测内存泄漏,以及利用Android Profiler进行性能分析。 通过深入研究《Android经典源码...

    Android应用源码之AsyncTask_Download2.zip

    通过分析和学习`AsyncTask_Download2`源码,我们可以深入了解Android中如何优雅地处理后台任务,特别是对于文件下载这种耗时操作。同时,这也有助于理解Android的多线程编程,提升应用性能和用户体验。

    Android应用源码之AsyncTask_Download2_应用.zip

    本项目"Android应用源码之AsyncTask_Download2_应用.zip"显然是一个以AsyncTask实现文件下载功能的示例代码。下面我们将深入探讨AsyncTask以及如何在Android中实现文件下载。 AsyncTask是Android SDK提供的一种轻量...

    Android程序源码--测试

    9. **异步编程**:Android提供了AsyncTask、Handler、Thread、Runnable等异步处理机制,源码分析可以学习如何避免主线程阻塞,提高应用响应性。 10. **权限管理**:Android的权限模型是安全管理的重要组成部分,...

    50款Android studio项目源码.zip

    通过以上分析,我们可以看出,这50个Android Studio项目源码几乎覆盖了Android开发的所有核心领域。每一个项目都是一个实战演练,对于初学者来说,不仅可以锻炼编程技巧,还能提升解决问题的能力。在实践中学习,是...

    Android经典源码实例全集

    5. **Fragment**:Fragment是Android大屏幕设计的重要组件,源码分析有助于理解它的生命周期、与Activity的交互以及如何处理回退栈。 6. **View绘制流程**:Android UI的基础是View和 ViewGroup,研究它们的绘制...

    Android5.0Email源码

    通过分析源码,我们可以学习以下几个方面的知识: 1. **Intent服务**:Android中的Intent服务是Android组件通信的核心机制,Email应用会使用Intent来启动邮件收发、同步和其他操作。 2. **ContentProvider**:...

    Android源码与教程

    4. **UI系统**:Android的UI框架基于View和 ViewGroup,源码分析可以揭示布局绘制流程、事件分发机制以及动画实现方式,有助于定制复杂的自定义视图和优化界面性能。 5. **权限管理系统**:Android的权限模型控制了...

Global site tag (gtag.js) - Google Analytics