README.md 7.94 KB
Newer Older
1
# react-native-threads
2

Travis Nuttall's avatar
Travis Nuttall committed
3 4 5
[![npm version](https://img.shields.io/npm/v/react-native-threads.svg?style=flat-square)](https://www.npmjs.com/package/react-native-threads)
[![downloads](https://img.shields.io/npm/dm/react-native-threads.svg?style=flat-square)](https://www.npmjs.com/package/react-native-threads)

6 7 8 9 10 11 12 13 14
Spawn new react native JavaScript processes for CPU intensive work outside of your
main UI JavaScript process.

Despite this package's name, this isn't real 'threading', but rather multi-processing.
The main tradeoff of using this library is memory usage, as creating new JS processes
can have significant overhead.  Be sure to benchmark your app's memory usage and other
resources before using this library! Alternative solutions include using `runAfterInteractions`
or the [Interaction Manager](https://facebook.github.io/react-native/docs/interactionmanager.html),
and I recommend you investigate those thoroughly before using this library.
15 16 17

## Getting started

18
`$ npm install react-native-threads --save`
19 20 21

### Mostly automatic installation

22
`$ react-native link react-native-threads`
23

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
### Android

For android you will need to make a slight modification to your `MainApplication.java`
file.  In the `getPackages` method pass in `mReactNativeHost` to the `RNThreadPackage`
constructor:

```java
    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new RNThreadPackage(mReactNativeHost)  // <-- Here
      );
    }
```

Also note that only the official react native modules are available from your
threads (vibration, fetch, etc...). To include additional native modules in your
threads, pass them into the `RNThreadPackage` constructor after the `mReactNativeHost`
like this:
`new RNThreadPackage(mReactNativeHost, new ExampleNativePackage(), new SQLitePackage())`

46 47 48 49 50 51
### Manual installation


#### iOS

1. In XCode, in the project navigator, right click `Libraries``Add Files to [your project's name]`
52
2. Go to `node_modules``react-native-threads` and add `RNThread.xcodeproj`
53 54 55 56 57
3. In XCode, in the project navigator, select your project. Add `libRNThread.a` to your project's `Build Phases``Link Binary With Libraries`
4. Run your project (`Cmd+R`)<

#### Android

58
1. Open up `android/app/src/main/java/[...]/MainApplication.java`
59
  - Add `import com.reactlibrary.RNThreadPackage;` to the imports at the top of the file
60 61 62 63 64 65 66
  - Add `new RNThreadPackage(mReactNativeHost)` to the list returned by the `getPackages()` method
  - Also note that only the official react native modules are available from your
    threads (vibration, fetch, etc...). To include additional native modules in your
    threads, pass them into the `RNThreadPackage` constructor after the `mReactNativeHost`
    like this:
    `new RNThreadPackage(mReactNativeHost, new ExampleNativePackage(), new SQLitePackage())`

67 68
2. Append the following lines to `android/settings.gradle`:
  	```
69 70
  	include ':react-native-threads'
  	project(':react-native-threads').projectDir = new File(rootProject.projectDir, 	'../node_modules/react-native-threads/android')
71 72 73
  	```
3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
  	```
74
      compile project(':react-native-threads')
75 76 77
  	```

#### Windows
78 79
Windows support is not yet implemented, but PRs are welcome if you want to give it a shot!

80 81
[Read it! :D](https://github.com/ReactWindows/react-native)

82
1. In Visual Studio add the `RNThread.sln` in `node_modules/react-native-threads/windows/RNThread.sln` folder to their solution, reference from their app.
83 84 85 86 87 88
2. Open up your `MainPage.cs` app
  - Add `using Thread.RNThread;` to the usings at the top of the file
  - Add `new RNThreadPackage()` to the `List<IReactPackage>` returned by the `Packages` method


## Usage
89 90 91

In your application code (react components, etc.):

92
```javascript
93 94 95 96 97 98 99
import { Thread } from 'react-native-threads';

// start a new react native JS process
const thread = new Thread('path/to/thread.js');

// send a message, strings only
thread.postMessage('hello');
100

101
// listen for messages
Jelte Liebrand's avatar
Jelte Liebrand committed
102
thread.onmessage = (message) => console.log(message);
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117

// stop the JS process
thread.terminate();
```

In your thread code (dedicated file such as `thread.js`):
```javascript
import { self } from 'react-native-threads';

// listen for messages
self.onmessage = (message) => {
}

// send a message, strings only
self.postMessage('hello');
118
```
119

120
Check out the examples directory in this repo for demos of using `react-native-threads`
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
in a functioning app!

### Thread Lifecycle

- Threads are paused when the app enters in the background
- Threads are resumed once the app is running in the foreground
- During development, when you reload the main JS bundle (shake device -> `Reload`) the threads are killed

### Debugging

Instantiating Threads creates multiple react native JS processes and can make debugging
remotely behave unpredictably. I recommend using a third party debugging tool like
[Reactotron](https://github.com/infinitered/reactotron) to aid with this. Each process,
including your main application as well as your thread code can connect to Reactotron
and log debugging messages.
136

137 138 139 140 141 142 143
### Building for Release

You will need to manually bundle your thread files for use in a production release
of your app.  This documentation assumes you have a single thread file called
`index.thread.js` in your project root.  If your file is named differently or in
a different location, you can update the documented commands accordingly.

Craig Coles's avatar
Craig Coles committed
144
**Note**: If your single thread file is in a different location, the folder structure needs to 
145 146 147 148 149 150 151
be replicated under `./ios` and `./android/app/src/main/assets/threads`.

```
./App/Workers/worker.thread.js => ./ios/App/Workers/worker.thread.jsbundle
./App/Workers/worker.thread.js => ./android/app/src/main/assets/threads/App/Workers/worker.thread.jsbundle
```

152 153
For iOS you can use the following command:

154
`node node_modules/react-native/local-cli/cli.js bundle --dev false --assets-dest ./ios --entry-file index.thread.js --platform ios --bundle-output ./ios/index.thread.jsbundle`
155 156 157 158 159

Once you have generated the bundle file in your ios folder, you will also need to add
the bundle file to you project in Xcode. In Xcode's file explorer you should see
a folder with the same name as your app, containing a `main.jsbundle` file as well
as an `appDelegate.m` file. Right click on that folder and select the 'Add Files to <Your App Name>'
160
option, which will open up finder and allow you to select your `ios/index.thread.jsbundle`
161 162 163
file. You will only need to do this once, and the file will be included in all future
builds.

Jelte Liebrand's avatar
Jelte Liebrand committed
164 165
For Android create this direactory
`mkdir ./android/app/src/main/assets/threads`
166

Jelte Liebrand's avatar
Jelte Liebrand committed
167 168 169
And then you can use the following command:

`node node_modules/react-native/local-cli/cli.js bundle --dev false --assets-dest ./android/app/src/main/res/ --entry-file index.thread.js --platform android --bundle-output ./android/app/src/main/assets/threads/index.thread.bundle`
170 171 172 173

For convenience I recommend adding these thread building commands as npm scripts
to your project.

174 175 176 177 178 179 180
## Example App
Included in this repository is a simple example application demonstrating basic
usage of react-native-threads. Look at `examples/SimpleExample/README.md` for
instructions on running it.  Here's how the app looks with the Reactotron debugger:

![SimpleExample Screen Capture](https://raw.githubusercontent.com/traviskn/react-native-threads/master/media/simplethreadexample.gif)

181 182 183 184 185 186 187 188 189 190 191 192 193
## Acknowledgements

This library was heavily inspired by two other packages both under the name of
`react-native-workers`.

The first was https://github.com/fabriciovergal/react-native-workers ,
and the second was https://github.com/devfd/react-native-workers

I ended up going with devfd's implementation strategy as it seemed more flexible
and feature-rich to me.  At the time of this writing neither library was functioning
on the latest version of react native, and neither seemed to be very actively maintained.

This library would not exist without those two reference implementations to guide me!