React Native 之Android端 Bolts库

React Native 之Android端Bolts库

前言

这是我们React Native框架源码剖析的第一篇文章。为什么要写Android端Bolts库介绍?因为在分析安卓端源码时,有大量的使用到了Bolts库,如果不对该库做简单介绍,会严重影响源码阅读。工欲善其事必先利其器,对该库有一个基本了解,对于安卓端RN源码的分析是必要的。

有一点要注意,Bolts库仅在安卓端使用,iOS并未使用该库。这是因为在新架构中,iOS更倾向于使用Swift的现代异步特性。即使是老的代码中,iOS端也可以使用像NSOperation、dispatch_async等这样的原生API。Android端是由于Java的异步编程复杂性,才选择了Bolts框架。

背景

在2013年,Parse 被Facebook 收购。并于2014年开源了一个面向iOS 和Android 的底层库集合,统称为Bolts。根据Parse 的公告,Bolts 是Parse 和Facebook 共同努力将两家公司各自独立开发的小型底层工具类合并的结果。

Tasks

Tasks 是GitHub 上第一个可用的Bolts 组件,旨在按照JavaScript Promises 模型处理异步操作,它同时适用于 iOS 和 Android 系统。简单说,它类似于Dart的Future和JavaScript的Promise。

Bolts-Android

Bolts-Android 是安卓平台的Java实现,于2020年停止维护。仓库地址

该库提供了这些功能:

  • 任务抛到某个线程执行:当前线程、后台线程、UI线程执行任务
  • 任务级联执行:UI线程、后台线程、UI线程执行任务
  • 任务并行执行:Task.whenAll多任务并行执行
  • 自定义任务线程池
  • 延时执行任务
  • 取消执行的任务

API 的使用

任务抛到某个线程执行

当前线程、后台线程、UI线程运行任务

Java 示例:

java 复制代码
// 运行在当前线程中
public Task<Boolean> runOnCurrentThread() {
   return Task.call(new Callable<Boolean>() {
       @Override
       public Boolean call() throws Exception {
           // Current_Thread
           return true;
       }
   });
}

// 运行在后台线程
public Task<Boolean> runOnBackgroundThread() {
   return Task.call(new Callable<Boolean>() {
       @Override
       public Boolean call() throws Exception {
           // Background_Thread
           return true;
       }
   }, Task.BACKGROUND_EXECUTOR);
}

// 运行在UI线程中
public Task<Boolean> runOnUIThread() {
   return Task.call(new Callable<Boolean>() {
       @Override
       public Boolean call() throws Exception {
           // UI_Thread
           return true;
       }
   }, Task.UI_THREAD_EXECUTOR);
}

Kotlin 示例:

kotlin 复制代码
// 运行在当前线程中
fun runOnCurrentThread(): Task<Boolean> {
    return Task.call(Callable {
        // Current_Thread
        true
    })
}

// 运行在后台线程
fun runOnBackgroundThread(): Task<Boolean> {
    return Task.call(Callable {
        // Background_Thread
        true
    }, Task.BACKGROUND_EXECUTOR)
}

// 运行在UI线程中
fun runOnUIThread(): Task<Boolean> {
    return Task.call(Callable {
        // UI_Thread
        true
    }, Task.UI_THREAD_EXECUTOR)
}

Kotlin 示例(使用标签语法,更简洁):

kotlin 复制代码
// 运行在当前线程中
fun runOnCurrentThread() = Task.call(Callable task@{
    // Current_Thread
    true
})

// 运行在后台线程
fun runOnBackgroundThread() = Task.call(Callable task@{
    // Background_Thread
    true
}, Task.BACKGROUND_EXECUTOR)

// 运行在UI线程中
fun runOnUIThread() = Task.call(Callable task@{
    // UI_Thread
    true
}, Task.UI_THREAD_EXECUTOR)
任务级联执行

Java 示例:

java 复制代码
// 任务顺序执行
public Task synchronousTask(CancellationToken cancellationToken) {
   return Task.call(new Callable<Void>() {
       @Override
       public Void call() throws Exception {
           // UI_Thread
           LogUtils.d(TAG, "---1 UI_Thread---");
           return null;
       }
   }, Task.UI_THREAD_EXECUTOR, cancellationToken).onSuccess(new Continuation<Void, Boolean>() {
       @Override
       public Boolean then(Task<Void> task) throws Exception {
           // Background_Thread
           LogUtils.d(TAG, "---2 Background_Thread---");
           return true;
       }
   }, Task.BACKGROUND_EXECUTOR).continueWith(new Continuation<Boolean, Void>() {
       @Override
       public Void then(Task<Boolean> task) throws Exception {
           // UI_Thread
           LogUtils.d(TAG, "---3 UI_Thread---");
           return null;
       }
   }, Task.UI_THREAD_EXECUTOR);
}

Kotlin 示例:

kotlin 复制代码
// 任务顺序执行
fun synchronousTask(cancellationToken: CancellationToken): Task<Void?> {
    return Task.call(Callable {
        // UI_Thread
        LogUtils.d(TAG, "---1 UI_Thread---")
        null
    }, Task.UI_THREAD_EXECUTOR, cancellationToken).onSuccess(Continuation { task ->
        // Background_Thread
        LogUtils.d(TAG, "---2 Background_Thread---")
        true
    }, Task.BACKGROUND_EXECUTOR).continueWith(Continuation { task ->
        // UI_Thread
        LogUtils.d(TAG, "---3 UI_Thread---")
        null
    }, Task.UI_THREAD_EXECUTOR)
}
任务并行执行

Java 示例:

java 复制代码
// 多任务并行
public void whenAll() {
   ArrayList<Task<Void>> tasks = new ArrayList<Task<Void>>();
   for (int i = 0; i < 3; i++) {
       final int index = i;
       // Start this delete immediately and add its task to the list.
       tasks.add(Task.call(new Callable<Void>() {
           @Override
           public Void call() throws Exception {
               // UI_Thread
               LogUtils.d(TAG, "---###########################---");
               LogUtils.d(TAG, "index: " + index);
               return null;
           }
       }, Task.BACKGROUND_EXECUTOR));
   }

   Task.whenAll(tasks);
}

Kotlin 示例:

kotlin 复制代码
// 多任务并行
fun whenAll() {
    val tasks = ArrayList<Task<Void?>>()
    for (i in 0 until 3) {
        // Start this delete immediately and add its task to the list.
        tasks.add(Task.call(Callable {
            // UI_Thread
            LogUtils.d(TAG, "---###########################---")
            LogUtils.d(TAG, "index: $i")
            null
        }, Task.BACKGROUND_EXECUTOR))
    }
    
    Task.whenAll(tasks)
}
自定义任务线程池

Java 示例:

java 复制代码
// 自定义线程池
static final Executor NETWORK_EXECUTOR = Executors.newCachedThreadPool();
static final Executor DISK_EXECUTOR = Executors.newCachedThreadPool();

public void changeThreadPool() {
   Task.call(new Callable<Boolean>() {
       @Override
       public Boolean call() throws Exception {
           // NETWORK_Thread
           return null;
       }
   }, NETWORK_EXECUTOR).continueWith(new Continuation<Boolean, String>() {
       @Override
       public String then(Task<Boolean> task) throws Exception {
           // NETWORK_Thread
           return null;
       }
   }).continueWith(new Continuation<String, Integer>() {
       @Override
       public Integer then(Task<String> task) throws Exception {
           // DISK_Thread
           return null;
       }
   }, DISK_EXECUTOR);
}

Kotlin 示例

kotlin 复制代码
// 自定义线程池
companion object {
    val NETWORK_EXECUTOR: Executor = Executors.newCachedThreadPool()
    val DISK_EXECUTOR: Executor = Executors.newCachedThreadPool()
}

fun changeThreadPool() {
    Task.call(Callable {
        // NETWORK_Thread
        null
    }, NETWORK_EXECUTOR).continueWith(Continuation { task ->
        // NETWORK_Thread
        null
    }).continueWith(Continuation { task ->
        // DISK_Thread
        null
    }, DISK_EXECUTOR)
}
延时执行任务

Java 示例:

java 复制代码
Task.delay(100).continueWith(new Continuation<Void, Void>() {
    @Override
    public Void then(Task<Void> task) throws Exception {
        mTcpSocketAgent.initClientSocket(serverIp);
        mTcpSocketAgent.addMsgCallback(mTcpMsgCallback);
        mTcpSocketAgent.startConnect();
        return null;
    }
}, Task.UI_THREAD_EXECUTOR);

Kotlin 示例:

kotlin 复制代码
Task.delay(100).continueWith(Continuation { task ->
    mTcpSocketAgent.initClientSocket(serverIp)
    mTcpSocketAgent.addMsgCallback(mTcpMsgCallback)
    mTcpSocketAgent.startConnect()
    null
}, Task.UI_THREAD_EXECUTOR)
取消执行的任务

Java 示例:

java 复制代码
// 取消任务
public void cancelTask() {
   CancellationTokenSource cts = new CancellationTokenSource();
   Task<Boolean> stringTask = runOnBackgroundThread(cts.getToken());
   cts.cancel();
}

// 运行在后台线程中
public Task<Boolean> runOnBackgroundThread(CancellationToken cancellationToken) {
   return Task.call(new Callable<Boolean>() {
       @Override
       public Boolean call() throws Exception {
           // Background_Thread
           return true;
       }
   }, Task.BACKGROUND_EXECUTOR, cancellationToken);
}

Kotlin 示例:

kotlin 复制代码
// 取消任务
fun cancelTask() {
    val cts = CancellationTokenSource()
    val stringTask = runOnBackgroundThread(cts.token)
    cts.cancel()
}

// 运行在后台线程中
fun runOnBackgroundThread(cancellationToken: CancellationToken): Task<Boolean> {
    return Task.call(Callable {
        // Background_Thread
        true
    }, Task.BACKGROUND_EXECUTOR, cancellationToken)
}
相关推荐
风月说与山鬼28 分钟前
三、大括号语法
前端·react.js
kyriewen42 分钟前
我把最常踩的8个CORS跨域报错整理了一遍——第8个去年还不存在
前端·javascript
Csvn1 小时前
🕰️ 闭包 + setTimeout 的 5 个经典陷阱:为什么定时器看到的永远不是最新的值?
前端
夜雪一千1 小时前
MySQL 全局锁是什么?原理、风险、备份踩坑完整实战
android·mysql·adb
lilian2332 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos
CarIise2 小时前
CSS选择器与样式关联
前端·css·tensorflow
里欧跑得慢3 小时前
CSS 模块化架构的演进:BEM、CSS Modules 到 CSS-in-JS 的反思
前端·css·flutter·web·css-in-js
IT_陈寒4 小时前
Vue的computed属性把我坑惨了,原来我一直用错姿势
前端·人工智能·后端
小灰灰搞电子4 小时前
Rust+Slint 实现温度计源码分享
前端·rust·slint