Why should a developer avoid using React native for multithreading- Part 1

Vikash SR

4 min read

Hello, everyone! This is my first blog, I hope you all enjoy it. After all, engineers are great problem solvers, right? We are expected to provide the finest & flexible solution for whatever situation exists. So I’ll be discussing how we solved the difficulty of handling multiple threads in our React-Native App, and how we accomplished it by providing a better approach.

Before we jump into the feature explanation part, let me give a quick glimpse of the project we worked on. It is a Healthcare Research project that helps the Cognitive Analysis Researchers/ Practitioners to observe, collect and store Brain Wave Pattern data of the Users, who are kids aged between 5 to 10 in the CSV format.

Recognizing the issue

Okay, I can understand your curiosity about what the problem is. So, for a better understanding, let me describe our app’s features that must be acknowledged. Our app is pretty intricate where every data in milliseconds is crucial and we need to collect the data and process it accordingly as per the client’s requirement. 

Our initial objective was to collect data from the user by tapping the screen that was displayed to them. Humans have a response time of 0.25 seconds on average. Surprising right?

Response
0
0
0.466
0.487
0
0.431

The above table shows the sample data acquired in milliseconds depending on a user’s tap on the screen, and we’ll need to collect comparable information based on the user’s answers.

Having completed collecting the data using JavaScript threads our next goal was to collect brain data using a Bluetooth Arduino device, which caused a problem due to it being in React-native.

To explain further,

as we know, React Native is an entire platform that allows you to create native, cross-platform mobile apps. It uses the JavaScript library and syntax for constructing applications. JavaScript is a single-threaded programming language. It has a single call stack and a single memory heap. It executes code in sequence, as intended, and must complete one piece of code before going on to the next.

The method we used to get the optimal solution:

There are several solutions to fix a problem, but selecting the best one might be difficult, here is one of the approaches that we considered applying to our app.

  • Third-party library: The first thing I did was look for some third-party libraries in React Native for multithreading. I know you’re laughing, but it’s all about time, and working smart is preferable to working hard. Finally, we found a suitable library called react-native-multithreading, one of the best third-party libraries we have in react native.
  • Challenge: Although it is an excellent library, there will always be a tiny overhead when calling spawnThread since all external variables must first be transferred into the new thread. If you utilize the separate thread to do sophisticated array operations, for example, we must remember that the array must first be copied into the separate thread. Which will result in performance differences.

Additionally, we must start and stop the data we are generating from the Arduino device as each game starts and sends, making this process expensive. According to our findings, when you run a lot of processes, performance suffers. As a result, we devised a plan to create a Native module.

We were scanning and connecting the Bluetooth device with a package called react-native-ble-manager, which made things a lot easier, and we started implementing the code in native Java inside the node module of the package the android.

What are Native Modules in React Native?

The Native Module system exposes Java/Objective-C/C++ (native) class instances as JS objects to JavaScript. This enables us to execute native code from within JS. If React Native doesn’t provide a native API that our JS project requires, we can create one, and yes, that is a complete lifesaver.

Before we can communicate with a BLE device, we must first understand the fundamental notions of BLE that are mentioned below.

  • BLE- What is that? Bluetooth Low Energy (BLE) is a subset of Bluetooth’s 2.4 GHz wireless technology that focuses on low power and infrequent data exchanges for connected devices.
  • Client / Central: A device that searches for and connects to Bluetooth Low Energy (BLE) peripherals in order to accomplish a task. This is usually an Android smartphone in the context of app development.
  • Peripheral: A device that broadcasts its presence and is linked to a client/ central in order to perform a task. In the context of app development, this is usually a BLE device, such as a heart rate monitor. In our case, it’s our Arduino device.
  • GATT Service: A set of characteristics (data fields) that describes a feature of a device, such as Device Information Service, which can have a characteristic indicating the device’s serial number and another reflecting the device’s battery level.
  • GATT Characteristic: An entity containing meaningful data that can typically be read from or written to, e.g. the Serial Number String characteristic.

The term communication here means, Reading and Writing the data so we need to get the service with the characteristics to read and write the data. From our app, we would do both operations.

  • Read: The client (app) reads the value of a characteristic or descriptor on the server / peripheral (BLE device) and interprets it based upon a protocol that has been established beforehand. For example, a smart thermostat may have a character whose value represents the current target temperature.
  • Write: The client (app) writes some bytes to a characteristic or descriptor on the server / peripheral (BLE device). The server’s firmware processes the write and performs some server-side operations in response to it. For example, a smart thermostat may have a characteristic that changes the target temperature when written to.

So, in order to get data from the peripheral, we must first write some bytes to the peripheral’s characteristics. To do so, we must first check for the characteristic to which the byte has to be sent.

The preceding Embedded C code, which has been installed in our peripheral, shows that eventChar has a BLEWrite action, and this is the characteristic where we will write from our client / central (App).

The above image is the logic we came up with for starting and stopping data from the peripheral using native modules, which will be done for each tap by the user in the mobile application. When we trigger a stop, the written CSV data will be saved on the mobile’s internal storage and then finally to firebase DB.

This is how we overcame the difficulties faced in handling multiple threads in our app. Hope this blog helps to solve your discrepancies too.

In the next part, we’ll look at how the logic is implemented in native Java and Objective-C. 🤓

Happy Learning!!

Related posts:

One Reply to “Why should a developer avoid using React native for…”

  1. Nice one… Can you share the source code for iOS got struck with integrating my module

Leave a Reply

Your email address will not be published. Required fields are marked *