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是自己的Handler:obtainMessage:通过what,obj获得msg;

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

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

    }

这下,你是不是明白呢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android网络连接源码分析主要涉及到Android系统中网络连接的相关实现和机制。下面是Android网络连接的源码分析: 1. 网络连接管理类:Android中的网络连接管理由ConnectivityManager类负责。该类提供了获取网络状态、监听网络状态变化等功能。其源码位于frameworks/base/core/java/android/net/ConnectivityManager.java。 2. 网络请求类:Android中的网络请求由HttpClient或HttpURLConnection实现。在Android 6.0及以上版本中,Google推荐使用HttpURLConnection。HttpClient的源码位于frameworks/base/core/java/org/apache/http/impl/client/DefaultHttpClient.java,HttpURLConnection的源码位于libcore/luni/src/main/java/java/net/HttpURLConnection.java。 3. 网络请求处理类:Android中的网络请求处理由AsyncTask或者Thread实现。AsyncTask是一个封装了线程池和Handler的异步任务类,用于在后台执行耗时操作,并在主线程更新UI。其源码位于frameworks/base/core/java/android/os/AsyncTask.java。 4. 网络请求结果处理类:Android中的网络请求结果处理由Handler或者Callback实现。Handler用于在主线程中处理异步任务的结果,Callback则是一种回调机制,用于在异步任务完成后执行相应的操作。 5. 网络缓存类:Android中的网络缓存由DiskLruCache或者LruCache实现。DiskLruCache用于将网络请求结果缓存到本地磁盘,LruCache则是一种内存缓存机制,用于缓存网络请求结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值