Bolts介绍

bolt是Parse和facebook开发的一个供内部使用的底层小工具集合,目前主要包括两方面的内容:
- “Tasks”,可以方便组织管理一系列复杂的异步任务代码,是对Javascript Promise模型的模仿。
- 提供一种App Links protocol的实现,帮助你链接到其他App中的内容和处理传入的deep-links。
本文只介绍Task部分。

官方定义:
A task represents an asynchronous operation. Typically, a Task is returned from an asynchronous function and gives the ability to continue processing the result of the task. When a task is returned from a function, it’s already begun doing its job. A task is not tied to a particular threading model: it represents the work being done, not where it is executing.
简单翻译:
一个任务表示异步操作。通常,一个任务是从一个异步函数返回,并给出了继续处理任务的结果的能力。当任务从一个函数返回时,它就已经开始做它的工作了。一个任务不是和一个特定的线程模型联系在一起:它代表了正在做的工作,而不是在执行的地方。

优点:
- 占用更少的系统资源,因为不会再等待其他任务时阻塞线程。
- 连续执行数个任务不会像只使用回调函数时那样创建嵌套的“金字塔(pyramid)”代码。
- Tasks是完全可组合的,允许开发人员执行分支、并行和复杂的错误处理。
- 开发人员可以按照执行顺序安排基于任务的代码,而不必将逻辑分解到分散的回调函数中。
常用函数:

  • Task.call和Task.callInBackground

该函数会在相关线程执行完任务后返回一个Task来标记任务的执行情况。

  • continueWith和continueWithTask

该函数会在当前task完成后调用Continuation.then方法,可以在该方法查看task是否成功,并获取其返回值。如果需要根据前一个的task返回状态来进行新的异步操作,可以使用continueWithTask方法来代替continueWith,该方法会返回一个新的task,除非新的task完成,否则continueWithTask返回的task也不会变成完成状态,通过这个可以有效的避免多重嵌套。

  • onSuccess和onSuccessTask

多数情况下,只有当前一个task完成你才会做后面的工作,该方法可以帮你先忽略不成功的任务,你可以在后面集中处理它们。

串行任务
一个任务接起前一个任务,只有当前一个任务执行完后,后一个任务才会执行。

Task.call(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                Bitmap bm = cacheMap.get(p);
                if (bm != null) {
                    iv.setImageBitmap(bm);
                    return SUCCESS;
                } else {
                    iv.setImageResource(R.drawable.default_img);
                }
                return FAIL;
            }
        }).onSuccessTask(new Continuation<Integer, Task<Bitmap>>() {
            @Override
            public Task<Bitmap> then(Task<Integer> task) throws Exception {
                int ret = task.getResult();
                if (ret == SUCCESS) {
                    Log.d(TAG, "task finish");
                    return Task.cancelled();
                } else {
                    synchronized (iv) {
                        iv.setTag(p);
                    }
                    return asyncDecodeTask(p);
                }
            }
        }).onSuccessTask(new Continuation<Bitmap, Task<Bitmap>>() {
            @Override
            public Task<Bitmap> then(Task<Bitmap> task) throws Exception {
                final Bitmap bm = task.getResult();
                if (bm != null) {
                    synchronized (iv) {
                        if (((String) iv.getTag()).equals(p)) {
                            iv.setImageBitmap(bm);
                        } else {
                            Log.d(TAG, "has scroll over");
                        }
                    }
                    return Task.cancelled();
                } else {
                    return asyncDownloadTask(p);
                }
            }
        }, Task.UI_THREAD_EXECUTOR).onSuccessTask(new Continuation<Bitmap, Task<Integer>>() {
            @Override
            public Task<Integer> then(Task<Bitmap> task) throws Exception {
                Bitmap bm = task.getResult();
                if (bm != null) {
                    asyncWriteTask(bm, p);
                    synchronized (iv) {
                        if (((String) iv.getTag()).equals(p)) {
                            iv.setImageBitmap(bm);
                        } else {
                            Log.d(TAG, "has scroll over");
                        }
                    }
                    return Task.cancelled();
                } else {
                    return Task.forResult(ERROR);
                }
            }
        }, Task.UI_THREAD_EXECUTOR).continueWith(new Continuation<Integer, Object>() {
            @Override
            public Object then(Task<Integer> task) throws Exception {
                if (task.isFaulted()) {
                    Log.i(TAG, "error log " + task.getError().getMessage());
                }
                if(task.isCancelled()){
                    Log.i(TAG, "has cancelled");
                }
                int ret = task.getResult();
                Log.d(TAG, "ret" + ret);
                return null;
            }
        });

上面是一段异步加载图片的代码,先从缓存中获取,拿不到就尝试从磁盘中获取,再拿不到就从上网络下载,以上只要某一步成功就会取消的后续任务,错误会在最后统一处理。
- 并行任务
如果需要多任务同时进行,要使用whenAll函数,传入一个任务列表。

Task.callInBackground(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                Log.d(TAG, "start download");
                URL url = new URL(FILE_URL);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);
                int code = conn.getResponseCode();
                Log.d(TAG, "code " + code);
                if (code == 200) {
                    int length = conn.getContentLength();
                    Log.d(TAG, "length" + length);
                    RandomAccessFile raf = new RandomAccessFile(FILE_NAME, "rwd");
                    //指定创建的这个文件的长度
                    raf.setLength(length);
                    capture.set(length);
                    raf.close();
                    return SUCCESS;
                }
                return FAIL;
            }
        }).onSuccessTask(new Continuation<Integer, Task<Void>>() {
            @Override
            public Task<Void> then(Task<Integer> task) throws Exception {
                List<Task<Void>> lst = new ArrayList<Task<Void>>();
                if (task.getResult() == SUCCESS) {
                    int length = capture.get();
                    int blockSize = length / THREAD_COUNT;
                    for (int i = 0; i < THREAD_COUNT; i++) {
                        if (i == THREAD_COUNT - 1) {
                            lst.add(asyncDownload(i * blockSize, capture.get(), FILE_URL, FILE_NAME));
                        } else
                            lst.add(asyncDownload(i * blockSize, (i + 1) * blockSize, FILE_URL, FILE_NAME));
                    }
                }
                return Task.whenAll(lst);
            }
        }).continueWith(new Continuation<Void, Object>() {
            @Override
            public Object then(Task<Void> task) throws Exception {
                if (task.isFaulted()) {
                    Log.e(TAG, task.getError().getMessage());
                }
                if(task.isCompleted())
                    Log.d(TAG, "finish task!");
                return null;
            }
        });

上面是一段多线程并行分片下载同一个文件的代码,只有当所有的任务全部完成后whenAll的返回值才会变成完成状态,capture是bolts提供的简单泛型封装,允许你在task之间传递数据。
个人理解:
Continuation相当于控制器,应该在Continuation.then中控制调用不同的task,根据返回的task来判断任务执行情况,但实际情况难免有些不同,也可以灵活变通,在then中写业务逻辑。
总结一下,task能方便的帮我们组织和管理异步操作的代码,有效解决回调嵌套问题,使代码结构清晰,但因为java是强类型语言,函数返回值单一,没有javascript灵活,bolts中广泛采用泛型,函数的返回值处理会比较麻烦。本文只是简单介绍,如果想详细了解Bolts和Promise异步编程模型可以参看下面的网站。

以上均是本人的个人理解,如有错误, 欢迎指正!

相关资料:
https://github.com/BoltsFramework/Bolts-Android

http://www.infoq.com/cn/news/2014/02/parse-announces-bolts

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

https://www.promisejs.org/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Series: Chapman & Hall/CRC Mathematical and Computational Biology Hardcover: 294 pages Publisher: Chapman and Hall/CRC (December 22, 2015) Language: English ISBN-10: 1498724523 ISBN-13: 978-1498724524 Demystifies Biomedical and Biological Big Data Analyses Big Data Analysis for Bioinformatics and Biomedical Discoveries provides a practical guide to the nuts and bolts of Big Data, enabling you to quickly and effectively harness the power of Big Data to make groundbreaking biological discoveries, carry out translational medical research, and implement personalized genomic medicine. Contributing to the NIH Big Data to Knowledge (BD2K) initiative, the book enhances your computational and quantitative skills so that you can exploit the Big Data being generated in the current omics era. The book explores many significant topics of Big Data analyses in an easily understandable format. It describes popular tools and software for Big Data analyses and explains next-generation DNA sequencing data analyses. It also discusses comprehensive Big Data analyses of several major areas, including the integration of omics data, pharmacogenomics, electronic health record data, and drug discovery. Accessible to biologists, biomedical scientists, bioinformaticians, and computer data analysts, the book keeps complex mathematical deductions and jargon to a minimum. Each chapter includes a theoretical introduction, example applications, data analysis principles, step-by-step tutorials, and authoritative references

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hainengbunengwan

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值