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)
}
相关推荐
Live000008 小时前
在鸿蒙中使用 Repeat 渲染嵌套列表,修改内层列表的一个元素,页面不会更新
前端·javascript·react native
阿巴斯甜15 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker16 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952717 小时前
Andorid Google 登录接入文档
android
黄林晴18 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android