Android级连异步任务——Bolts-Android源码简单学习(二)

来源:互联网 发布:ember.js form表单 编辑:程序博客网 时间:2024/04/29 03:12

Parse开源了一个面向iOS和Android的底层库集合,统称为Bolts。根据Parse的公告,Bolts是Parse和Facebook共同努力将两家公司各自独立开发的小型底层工具类合并的结果。Bolts-Android为一个级联的异步任务。

Bolts-Android github地址:
https://github.com/BoltsFramework/Bolts-Android

本文案例的 github地址:
https://github.com/xiaxveliang/Android_ThirdSource_Bolts

读后收获:

  • 级连异步任务,可按以下方式使用
Task.call(new Callable<Boolean>() {    @Override    public Boolean call() throws Exception {        return true;    }}, Task.BACKGROUND_EXECUTOR).continueWith(new Continuation<Boolean, Object>() {    @Override    public Object then(Task<Boolean> task) throws Exception {        return null;    }}, Task.BACKGROUND_EXECUTOR).continueWith(new Continuation<Object, Boolean>() {    @Override    public Boolean then(Task<Object> task) throws Exception {        return true;    }}, Task.UI_THREAD_EXECUTOR);
  • 可自定义线程池,来处理不同类型的任务
    例如,我们除了有Task.BACKGROUND_EXECUTOR线程池,还可以有 NETWORK_EXECUTOR(只处理网络请求)、DISK_EXECUTOR(只处理Sdcard的读写)等线程池。
  • 可通过Task类waitForCompletion()方法,阻塞当前线程,直到Task任务运行结束
  • 每一个Task类的对象,均包含一个Continuation列表,用来管理当前Task对象全部的Continuation任务
    // 每一个Task对象都有一个自己的Continuation队列(continuations非全局,这样不同task的continuation就不会混淆)    private List<Continuation<TResult, Void>> continuations = new ArrayList<>();
  • Continuation任务的执行时机
    当前Task对象的call()方法运行结束后,会调用trySetResult()方法,将运行结果保存下来;并循环执行continuations列表中的任务。
    Task.java类中trySetResult方法:
    //当前task,执行结束后的返回数据赋值    //Sets the result on the Task if the Task hasn't already been completed.    boolean trySetResult(TResult result) {        synchronized (lock) {            // 任务运行结束判断            if (complete) {                return false;            }            // 任务运行结束            complete = true;            // 任务结果赋值            Task.this.result = result;            // 唤醒lock wait等待(如果之前调用过waitForCompletion阻塞线程,那么此处会被唤醒)            lock.notifyAll();            // 循环执行continuations任务            runContinuations();            return true;        }    }

Task.java类中runContinuations方法:

//循环执行continuations任务//问题: Continuation并没有区分执行线程呀?//答:每一个Continuation又是一个封装的Continuation.then(),方法中将任务提交到的不同线程池private void runContinuations() {    synchronized (lock) {        // 循环运行当前continuations列表任务        for (Continuation<TResult, ?> continuation : continuations) {            try {               // 执行Continuation任务                continuation.then(this);           } catch (RuntimeException e) {                throw e;            } catch (Exception e) {                throw new RuntimeException(e);            }       }        // 当前Task的continuations队列置空       continuations = null;    }}

问题:continuations如何将不同任务提交到不用的线程池呢???
答:每一个Continuation又是一个封装的Continuation.then(),方法中将任务提交到的不同线程池

Task.java类中continueWith方法:

public <TContinuationResult> Task<TContinuationResult> continueWith(        final Continuation<TResult, TContinuationResult> continuation, final Executor executor,        final CancellationToken ct) {    // 上次task的完成情况    boolean completed;    // 构建一个新的task    final TaskCompletionSource<TContinuationResult> tcs = new TaskCompletionSource<>();    //    synchronized (lock) {        // 上次task的完成情况        completed = this.isCompleted();        // 如果上次task 未完成,添加到task列表        if (!completed) {            // 向continuations队列中添加一个“需提交到不同线程池执行的task任务”            this.continuations.add(new Continuation<TResult, Void>() {                @Override                public Void then(Task<TResult> task) {                    //                    completeImmediately(tcs, continuation, task, executor, ct);                    return null;                }            });        }    }    // 上次任务完成,当前线程执行    if (completed) {        completeImmediately(tcs, continuation, this, executor, ct);    }    //    return tcs.getTask();}

这里可以看出每次提交的Continuation任务中,均封装了一个completeImmediately(tcs, continuation, task, executor, ct);来确定其运行的线程池等信息。

0 0
原创粉丝点击