Android AsyncTask的源码分析

1. AsyncTask的实现原理简介

首先抛出一个问题,如何在不用AsyncTask的情况下实现异步下载一张图片并在一个ImageView中显示?
可以这么做,创建一个线程,在这个线程中下载图片,然后通过Handler消息机制在UI主线程中显示这张图片。大致代码如下:

public class MainActivity extends Activity {
   

    private ImageView mImageView;

    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            Bitmap result = (Bitmap) msg.obj;
            switch (msg.what) {
                case MESSAGE_POST_RESULT:
                    // There is only one result
                    mImageView.setImageBitmap(result);
                    break;
            }
        }
    }

    private void executeDownloadImageTask(Uri uri) {
        new Thread(new Runnable() {

            public void run() {
                Bitmap bitmap = downloadImage(uri);
                Message msg = Message.obtain();
                msg.what = MESSAGE_POST_RESULT;
                msg.obj = bitmap;
                mHandler.sendMessage(msg);
            }
        }).start();
    }
}

上述实现有一个缺陷,每次执行executeDownloadImageTask方法都会创建一个新的线程,当有大量的图片下载请求时,线程的数量就不可控,大量的线程之间可能因为互相抢占系统资源而导致阻塞,同时线程的创建和销毁都会带来性能开销。AsyncTask的实现与上述方法唯一不同的地方正是使用了线程池来管理线程。AsyncTask类中的方法onPostExecute(Result result)能在UI线程中处理结果,正是利用了Handler消息机制将执行doInBackground方法的返回结果传递到了UI线程。

在学习AsyncTask源码前,请先了解以下概念

  • Callable<V>
  • FutureTask<>
  • Executor
  • 线程池

若不了解,请参考博文Java Executor
下面就来具体分析一下AsyncTask的源码。

2. AsyncTask源码分析

整个AsyncTask由3部分组成,任务FutureTask,线程池Executor,与UI线程关联的Handler,结构示意图如下:
这里写图片描述

2.1 创建任务

AsyncTask中的doInBackground方法会在非UI线程中执行,如何将其封装为一个任务类。源码如下:

public AsyncTask() {
    mWorker = new WorkerRunnable<Params, Result>() {
        public Result call() throws Exception {
            mTaskInvoked.set(true);

            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            //noinspection unchecked
            return postResult(doInBackground(mParams));
        }
    };

    mFuture = new FutureTask<Result>(mWorker) {
        @Override
        protected void done() {
            try {
                postResultIfNotInvoked(get());
            } catch (Interrupte
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值