博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AsyncTask工作机制简介
阅读量:5738 次
发布时间:2019-06-18

本文共 9059 字,大约阅读时间需要 30 分钟。

昨天写的图片的三级缓存,假设有兴趣,能够去看下,

在里面我们下载的时候。採用了AsyncTask异步下载机制,那么今天就来浅谈一下AsycnTask工作机制吧。

首先我们来看下AsyncTask的官方解释

  • AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.
  • AsyncTask的设计是环绕主题和Handler一个辅助类,并不构成通用线程框架。异步任务最好应(至多几秒钟。)可用于短期操作。假设您须要保持对长时间运行的线程。强烈建议您使用java.util.concurrent包等提供的各种API作为遗嘱运行人。并ThreadPoolExecutor的FutureTask提供。

    (英文不太好,google翻译的哈)

  • An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
  • AsyncTask是定义异步任务在后台线程(子线程中)运行的。而结果更新UI在UI线程中,接收三个參数,Params(传入的值)Progress(进度) Result(返回的结果)。有四步onPreExecute(在UI线程中运行,准备操作)doInBackground(子线程中耗时操作)onProgressUpdate (进度更新)onPostExecute(结果返回)
    使用方法我就不解释了。能够去官网看下使用方法,这里仅仅说明异步机制。

好了,那我们就来看下源代码运行的操作吧。首先我们从刚開始出发,也就是execute()。

new MyAsync().execute(imageView,url);

AsyncTask的execute()方法:

This method must be invoked on the UI thread.(必须在UI线程中调用)  @MainThread    public final AsyncTask
execute(Params... params) { //在这里调用了executeOnExecutor()方法 return executeOnExecutor(sDefaultExecutor, params); }

来看下executeOnExecutor()方法:

@MainThread(主线程中调用的)    public final AsyncTask
executeOnExecutor(Executor exec, Params... params) { //这里有一些异常的推断 。因为代码量多。我就去掉了,在这里我们不考虑异常问题 //在这里首先吧状态给位RUNNING mStatus = Status.RUNNING; //运行前的准备工作 onPreExecute(); //这里的params就是我们传入的值,然后赋值给了mWorker,那么我们就要看看这个是什么意思了 mWorker.mParams = params; //用线程池运行这个future exec.execute(mFuture); //终于返回自己 return this; }

mWorker參数的构造:

/**     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.     */    public AsyncTask() {        //在构造方法中创建mWorker        mWorker = new WorkerRunnable
() { //这种方法,一会会用到 public Result call() throws Exception { mTaskInvoked.set(true); //设置线程优先级 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked //在这里运行耗时操作,传入我们传入的參数,告诉他要干什么 Result result = doInBackground(mParams); Binder.flushPendingCommands(); //这个得有值的时候运行 return postResult(result); } };

FutureTask中的方法调用:

//然后传递给这个类,把mWorker当做參数传递给FutureTask。        mFuture = new FutureTask
(mWorker) { @Override protected void done() { //一些异常处理 }; }

那么我们来看下FutureTask这个类做了些什么(接受到mWorker之后):

public FutureTask(Callable
callable) { if (callable == null) throw new NullPointerException(); //把mWorker传递给了callable,那么接下来就得看看callable在做什么了 this.callable = callable; //状态更新 this.state = NEW; // ensure visibility of callable }
public void run() {        if (state != NEW ||            !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))            return;        try {        //在这里把mWorker给了Callable               Callable
c = callable; if (c != null && state == NEW) { //这里的V就是一个结果的返回类型 V result; boolean ran; try { //事实上就是mWorker.call() 把耗时操作得到的结果给了result result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) //得到result结果,传递给set方法。调用set方法 set(result); } } //异常处理 }

set(result) 方法运行:

//Sets the result of this future to the given value unless     * this future has already been set or has been cancelled.     * 把结果也就是future当做參数传递进去。除非这个已经传了或者任务被取消     * / protected void set(V v) {        if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {        //在这,把result结果给了outcome。        //传递给outcome            outcome = v;            U.putOrderedInt(this, STATE, NORMAL); // final state            finishCompletion();        }    }

那么接下来就把result给了outcome,我们来看下这个是什么吧:

是一个object对象private Object outcome;//在这里把result传递给了x(object对象)        Object x = outcome;        if (s == NORMAL)        //返回future            return (V)x;        if (s >= CANCELLED)            throw new CancellationException();        throw new ExecutionException((Throwable)x);    }

这个时候我们就得到了mFuture对象,我们看看这个干了些什么:

//因为V就是result,在这里把返回的结果传入。然后运行done()方法    mFuture = new FutureTask
(mWorker) { @Override protected void done() { //异常 };
我们看下mFUture做的什么了        //在这里对mFuture进行了get()方法的回调        public final Result get() throws InterruptedException, ExecutionException {        //在这里又调用了FutureTask里面的方法        return mFuture.get();

FutureTask里面的get()方法:

/**     * @throws CancellationException {@inheritDoc}     */    public V get() throws InterruptedException, ExecutionException {        int s = state;   //得到当前的状态        if (s <= COMPLETING)            s = awaitDone(false, 0L);            //把当前状态传递给report中        return report(s);    }

我们能够看到在get方法中。最后返回了report(s),那就继续跟进去:

/**     * Returns result or throws exception for completed task.     *     * @param s completed state value     */    @SuppressWarnings("unchecked")    private V report(int s) throws ExecutionException {        Object x = outcome;        if (s == NORMAL)        //直接return回了result   也就是callable.call()方法的结果,或者说是mWorker.call()方法,把DoInBackground()方法返回            return (V)x;        if (s >= CANCELLED)            throw new CancellationException();        throw new ExecutionException((Throwable)x);    }

这里我们就得到了结果result:

//     mWorker = new WorkerRunnable
() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked //在这里运行了耗时操作 Result result = doInBackground(mParams); Binder.flushPendingCommands(); //调用postResult()这种方法,开启了子线程,把结果传了进去 return postResult(result); } };

看下postResult(result)方法:

private Result postResult(Result result) {        @SuppressWarnings("unchecked")        //在这里得到的message。然后发出   发送了 MESSAGE_POST_RESULT        Message message =         //发送消息        getHandler().obtainMessage(MESSAGE_POST_RESULT,        //this就是AsyncTask                new AsyncTaskResult
(this, result)); message.sendToTarget(); //返回result return result; }

AsyncTaskResult(this,result)方法:

@SuppressWarnings({
"RawUseOfParameterizedType"}) private static class AsyncTaskResult { final AsyncTask mTask; final Data[] mData; //这里的data。就是我们返回的结果 AsyncTaskResult(AsyncTask task, Data... data) { mTask = task; mData = data; } }

我们看下getHandler()方法:

//在这里创建了handler     private static Handler getHandler() {        synchronized (AsyncTask.class) {            if (sHandler == null) {            //在这里new 除了一个handler                sHandler = new InternalHandler();            }            //返回一个handler对象            return sHandler;        }    }

我们看下InternalHandler()方法:

//继承handler,在这里创建了handler    private static class InternalHandler extends Handler {
public InternalHandler() { super(Looper.getMainLooper()); } @SuppressWarnings({
"unchecked", "RawUseOfParameterizedType"}) @Override public void handleMessage(Message msg) { AsyncTaskResult
result = (AsyncTaskResult

>) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: //匹配到MESSAGE_POST_RESULT 。在这里处理结果 //接受耗时操作完毕后传递的消息 // There is only one result //调用了asynctask的finish()方法,传递的值就是之前耗时操作返回的结果 result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } } }

最后调用finish()方法:

private void finish(Result result) {        if (isCancelled()) {        //取消            onCancelled(result);        } else {        //调用了主线程,耗时操作已经完毕。更新UI,在主线程中运行            onPostExecute(result);        }        //在这里把状态改为FINISHED        mStatus = Status.FINISHED;    }

在这里,耗时操作就已经所有完毕了,状态也改为了FINISHED。到此为止。异步完毕。

  • AsyncTask工作机制也就这么多了。

    当然我们仅仅是考虑了正确工作的状态,也就是请求成功的哈,异常的,取消的,中断的在这里并没有做出解释。

    相信大家去看下源代码也是能够晓得原理的。

  • 因为小弟才疏学浅,也仅仅能简单的走一下源代码。自己理解有限。有些地方凝视的过于简单,希望大家谅解,假设有独特的,好的解释,希望大神们能够赐教一下。在这里小弟不胜感激。(QQ:1069584784)

转载地址:http://zgyzx.baihongyu.com/

你可能感兴趣的文章
POI getDataFormat() 格式对照
查看>>
Python 中的进程、线程、协程、同步、异步、回调
查看>>
好的产品原型具有哪些特点?
查看>>
实现java导出文件弹出下载框让用户选择路径
查看>>
刨根问底--技术--jsoup登陆网站
查看>>
OSChina 五一劳动节乱弹 ——女孩子晚上不要出门,发生了这样的事情
查看>>
Spring--通过注解来配置bean
查看>>
pandas 十分钟入门
查看>>
nginx rewrite
查看>>
前端安全系列(一):如何防止XSS攻击?
查看>>
IK分词器安装
查看>>
查看Linux并发连接数
查看>>
你是谁不重要,关键是你跟谁!
查看>>
CSS中规则@media的用法
查看>>
pychecker:分析你的python代码
查看>>
css 默认不显示 之后显示
查看>>
我的友情链接
查看>>
DNS显性+隐性URL转发原理
查看>>
我的友情链接
查看>>
网易有道 IP地址、手机号码归属地和身份证 查询接口API
查看>>