`
寻梦者
  • 浏览: 625945 次
  • 性别: 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 源码解析

    代码为博客的示例代码,有问题请博客中留言:http://blog.csdn.net/lmj623565791/article/details/38614699

    Android AsyncTask源码分析

    本文先简要介绍AsyncTask的用法,然后分析具体实现。 基本用法 AsyncTask是一个抽象类,我们需要创建子类去继承它,并且重写一些方法。AsyncTask接受三个泛型参数: Params: 指定传给任务执行时的参数的类型 ...

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

    异步任务Asynctask源码与反编译对比,来分析源代码

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

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

    Android AsyncTask实现机制详细介绍及实例代码

    主要介绍了Android AsyncTask实现机制详细介绍及实例代码的相关资料,这里附有示例代码,帮助大家学习理解,需要的朋友可以参考下

    Android AsyncTask完全解析 带你从源码的角度彻底理解

    我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制。...不过今天我还是准备从AsyncTask的基本用法开始讲起,然后我们再来一起分析下AsyncTask源码,看看它

    Java最全面试题宝典.rar

    AsyncTask源码分析 插件化技术 自定义控件 事件分发机制 ANR问题 Art和Dalvik的区别 Android关于OOM的解决方案 Fragment Activity&Fragment SurfaceView Android几种进程 APP启动过程 Activity启动流程以及界面展示...

    最全java面试题.zip

    AsyncTask源码分析 插件化技术 自定义控件 事件分发机制 ANR问题 Art和Dalvik的区别 Android关于OOM的解决方案 Fragment Activity&Fragment SurfaceView Android几种进程 APP启动过程 Activity启动流程以及界面展示...

    Android代码-AndroidNote Android笔记

    ListView源码分析 VideoView源码分析 View绘制过程详解 网络部分 HttpURLConnection详解 HttpURLConnection与HttpClient volley-retrofit-okhttp之我们该如何选择网路框架 Volley源码分析 Retrofit详解(上) Retrofit...

    Android中AsyncTask与handler用法实例分析

    主要介绍了Android中AsyncTask与handler用法,以实例形式较为详细的分析了Android中AsyncTask与handler的功能、用法与相关注意事项,并附带完整实例源码供读者下载,需要的朋友可以参考下

    Android通过Handler与AsyncTask两种方式动态更新ListView(附源码)

    主要介绍了Android通过Handler与AsyncTask两种方式动态更新ListView的方法,结合实例形式分析了ListView动态更新的常用技巧,并附上完整实例源码供读者下载,需要的朋友可以参考下

    android开发资料大全

    Android核心分析28篇,强烈推荐android初学者,android进阶者看看这个系列教程 Android应用开发者指南:性能优化 android开发教程合集(推荐新手看下这一季教程) 新手入门 会员贡献电子图书整理(内含PDF下载) ...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    本书是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。本书从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层...

    Android开发艺术探索

    《Android开发艺术探索》是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。《Android开发艺术探索》从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些...

    android异步消息机制 从源码层面解析(2)

    它提供了Params, Progress和 Result三个泛型参数,在下面会仔细分析这三个泛型参数的具体含义。 AsyncTask提供了四个核心方法 onPreExecute() 此方法在主线程中执行,在异步任务执行之前,此方法会被调用,一般用于...

    AsyncTaskDemo

    介绍了AsyncTask的使用,及源码分析。线程池,有返回值的线程。

    浅谈Android中多线程切换的几种方法

    我们知道,多线程是Android开发中必现的场景,很多原生API和开源项目都有多线程的内容,这里简单总结和探讨一下常见的多线程切换方式。 我们先回顾一下Java多线程的几个基础内容,然后再分析总结一些经典代码中对于...

Global site tag (gtag.js) - Google Analytics