Android 阅读源码,让你彻底理解AsyncTask运行原理

很久没写博客了,说实话,我也真是懒,但是久来久之如果你不写博客的话,那么你之前的知道的东西,可能就忘光了,我发现在你找工作的时候,付出的代价是非常的大的,所以我决定下定决心,重拾文笔,来记录自己的学习历程,我也希望大家不要懒,多写写博客,或者使用印象笔记等之类的软件来记笔记。好了,废话不多说,我们今天就来说说主题吧,如题所示,大家就应该知道我想要说什么了,至于为什么要说这个,是因为在面试中,这个AsyncTask的原理几乎都会问,其实,这个在Android中用的也是比较多的,在Android中也是比较经典的。那么AsyncTask的优缺点有以下这么几个:
使用的优点:
简单,快捷
过程可控
使用的缺点:
在使用多个异步操作和并需要进行UI变更时,就变得复杂起来.

开启源码之旅 :

其实AsyncTask的原理就是Handler+Thread,在我们使用AsyncTask一般会重写以下这么几个核心方法:

new AsyncTask(){
            @Override
            protected void onPreExecute() {//在异步任务之前会调用,可以做一些准备工作,比如dialog的弹出之类的
                super.onPreExecute();
            }

            @Override
            protected void onProgressUpdate(Object[] values) {
            //这个根据方法签名就能知道,他是用来更新进度条的,也就是说,后台有数据更新的时候,回调用
                super.onProgressUpdate(values);
            }

            @Override
            protected void onPostExecute(Object o) {//这个是,异步任务执行完之后会被调用,将结果返回
                super.onPostExecute(o);
            }

            @Override
            protected Object doInBackground(Object[] params) {//这个是在子线程中执行的,用来执行耗时人物,这里面的可以你的网络逻辑之类等
                return null;
            }





        }.execute(null);

通过上面几个核心方法的介绍,下面我们就来真正进入到AsyncTask内部看看,首先我们来看看异步任务的构造方法:

public AsyncTask() {
        //这里我以罗马数字来代替他们分别执行的步骤,根据我的步骤来
        //1.这个是一个CallAble类型的,我们去看看这个到底是什么,请看2.
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);//标记,用来屏蔽FutureTask中的done方法,至于为什么要弄一个falg,那是因为步骤6中set()方法,又会重新通过FutureTask里的done()方法,最终调用的postResult()方法再次把结果通过handler处理一遍,这样就不好了,所以弄了这么一个flag

                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//设置了线程优先级
                //noinspection unchecked
                Result result = doInBackground(mParams);//看到没有,这里调用donInBackground方法,这个是在子线程中执行的
                Binder.flushPendingCommands();
                return postResult(result);//这个方法我们待会看一下里面的实现,其实他就是把结果通过Handler来处理,最后调用onPostExecute,将结果传回主线程中,我们继续看这个方法的实现,请看步骤7.
            }
        };
        //4.这是一个FutureTask,其实他就是一个Runnable类型,我们看,在这里他把一个mWorker实例传给了FutureTask构造方法了。
        mFuture = new FutureTask<Result>(mWorker) {
            @Override
            protected void done() {
                try {
                    postResultIfNotInvoked(get());
                } catch (InterruptedException e) {
                    android.util.Log.w(LOG_TAG, e);
                } catch (ExecutionException e) {
                    throw new RuntimeException("An error occurred while executing              doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }
//5.执行execute方法,看这个作了什么操作:
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
            Params... params) {
       //....省略了

        onPreExecute();//这个方法是不是很熟悉,我们之前介绍过了

        mWorker.mParams = params;//将你传来的参数赋值给步骤2中的成员变量mParams,他是一个数组,因为可变参数嘛,对不对。
        exec.execute(mFuture);//好了,开始执行了,将这个mFuture对象(Runnable类型),会通过execute方法来处理。

        return this;
    }
//6.run方法的实现,主要的实现都是在这里的
public void run() {
       //......
        try {
            Callable<V> c = callable;//我们之前传进来了一个callable实例
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();//在这里会调用call()方法。我们看看步骤1中,子类的实现
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)//这里为true时,将会执行done()方法,这里就不贴代码了,自己可以去源码
                    set(result);
            }
        }.......
    }
//2.发现它实现了一个Callable接口,那么这个Call又是什么东西呢?我们看一下步骤3.
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
        Params[] mParams;
   }
//3.我们知道线程都是运行都是没有返回值的,那么后来在Java1.5版本对线程作了改进,就是这个,让他有返回值了。好,接着我们第4步。
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}
//7.postReust方法的具体实现:
  private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        //我们是不是,这里是不是通过Handler拿到一个消息,然后发送,我们继续看步骤8,看他具体怎么处理的
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }
    //8.handlerMessage消息处理:
    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]);//看看,拿到结果,那么这个mTask是什么呢?他就是一个AsyncTask的一个实例,调用finish方法,然后没看看这里怎么实现的额.步骤9.
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);
                    break;
            }
        }
        //9.finish()方法的具体实现,这里其实就是调用了onPostExecute
        private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);//看到没有,将结果返回了,是不是,到这里,它的原理就基本结束了
        }
        mStatus = Status.FINISHED;
    }

结束语:

今天的分析就到这里,可能有人看不太懂,但是有一定经验都能看的懂,由于很久没写博客了,语法表达上也退化了,由于水平有限,如有不好的地方,欢迎大家拍砖、吐槽,我会虚心接受。转载请注明出去,谢谢

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值