返回介绍

3.1、AsyncTask 构造函数

发布于 2024-12-23 22:31:12 字数 3792 浏览 0 评论 0 收藏
   /**AsyncTask 的构造函数源码片段**/
   public AsyncTask() {
    mWorker = new WorkerRunnable<Params, Result>() {
      //异步任务执行的时候回调 call 方法
      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);
      }
    };

    mFuture = new FutureTask<Result>(mWorker) {
      //任务执行完毕后会调用 done 方法
      @Override
      protected void done() {
        try {
          //get() 表示获取 mWorker 的 call 的返回值,即 Result.然后看 postResultIfNotInvoked 方法
          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);
        }
      }
    };
  }

AsyncTask 的实例化是在 UI 线程中。

  //@MainThread 表示这个动作是在 UI 线程中完成
  @MainThread
  public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
  }

构造函数初始化了两个成员变量 mWorker 和 mFuture。mWorker 为 WorkerRunnable 类型的匿名内部类实例对象(实现了 Callable 接口),mFuture 为 FutureTask 类型的匿名内部类实例对象,将 mWorker 作为 mFuture 的形参(重写了 FutureTask 类的 done 方法)。

  • WorkerRunnable 是一个实现了 Callable 的抽象类,扩展了 Callable 多了一个 Params 参数
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> 
{
    Params[] mParams;
}//java

下面讲述下 Callable 和 Runnable 的区别。

  • Callable 的接口方法是 call,Runnable 是 run
  • Callable 可以带返回值,Runnable 不行,结果通过 Future.get() 获取
  • Callable 可以捕获异常,Runnable 不行
public class CallableAndFuture {
  public static void main(String[] args) {
    Callable<Integer> callable = new Callable<Integer>() {
      public Integer call() throws Exception {
        return new Random().nextInt(100);
      }
    };
    //那 WorkerRunnable 的回调方法 call 肯定是在 FutureTask 中调用的
    FutureTask<Integer> future = new FutureTask<Integer>(callable)
    );
    new Thread(future).start();
    try {
      Thread.sleep(5000);// 可能做一些事情
      System.out.println(future.get());
    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (ExecutionException e) {
      e.printStackTrace();
    }
  }
}//java

FutureTask 的构造函数如下,

  public FutureTask(Callable<V> callable) {
    if (callable == null)
      throw new NullPointerException();
    //将 AsyncTask 里面初始化的 callable 赋值给 FutureTask 里面的 callable,证实了 WorkerRunnable 的回调方法 call 肯定是在 FutureTask 中调用的
    this.callable = callable;
    this.state = NEW;     // ensure visibility of callable
  }

查看 FutureTask 类,它实现了接口 Runnable

public class FutureTask<V> implements RunnableFuture<V>//java
实现了 RunnableFuture 接口

作为 Runnable 被线程执行,同时将 Callable 作为构造函数的参数传入,这样组合的好处是,假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过 Future 得到。FutureTask 的 run 方法要开始回调 WorkerRunable 的 call 方法了,call 里面调用 doInBackground(mParams),终于回到我们后台任务了,调用我们 AsyncTask 子类的 doInBackground() ,由此可以看出 doInBackground() 是在子线程中执行的,如下图所示

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。