Slide 1

Slide 1 text

React Native for Android Olivia Bishop Engineering Manager, Facebook

Slide 2

Slide 2 text

What is React Native for? Why it might be useful to an Android developer How it works Agenda React basics

Slide 3

Slide 3 text

What is React Native for?

Slide 4

Slide 4 text

Native apps can be great experiences • Snappy gestures and animations • Look good on Android • Integrate well with the OS

Slide 5

Slide 5 text

But they come with challenges 1. Slow to iterate (build & install) 2. Hard to learn (different environments for each platform) 3. Imperative APIs

Slide 6

Slide 6 text

Mobile web is not the answer

Slide 7

Slide 7 text

React can be used to describe native components No DOM No WebView

Slide 8

Slide 8 text

React Native http://facebook.github.io/react-native/

Slide 9

Slide 9 text

SOLUTIONS CHALLENGES INSTANT RELOAD BUILD & INSTALL 
 ON EVERY CHANGE 1 DECLARATIVE APIS IMPERATIVE APIS 3 SINGLE ENVIRONMENT FOR MULTIPLE PLATFORMS DIFFERENT ENVIRONMENTS FOR EACH PLATFORM 2

Slide 10

Slide 10 text

Write Once Run Anywhere NOT

Slide 11

Slide 11 text

Learn Once Write Anywhere (but share code when you can)

Slide 12

Slide 12 text

React basics

Slide 13

Slide 13 text

React A declarative way to build UI

Slide 14

Slide 14 text

8 99+

Slide 15

Slide 15 text

Imperative UI = Define Transitions

Slide 16

Slide 16 text

8 99+ ADD BADGE! SET BADGE TO 8!

Slide 17

Slide 17 text

8 99+ ADD BADGE! ADD FIRE! SET BADGE TO 99+!

Slide 18

Slide 18 text

if (count > 99) { if (!hasFire()) {
 addFire();
 } } else { if (hasFire()) {
 removeFire();
 }
 } if (count === 0) { if (hasBadge()) {
 removeBadge();
 } return;
 } if (!hasBadge()) {
 addBadge();
 } var countText = count > 99 ? '99+' : count.toString(); getBadge().setText(countText); Imperative

Slide 19

Slide 19 text

8 99+ 8 99+ 8 8 8 8 99+ 99+ 99+ 99+ 3 states 9 transitions

Slide 20

Slide 20 text

Declarative UI = Define States

Slide 21

Slide 21 text

Declarative if (count === 0) { return
; 8 } else if(count <= 99) { return (
); 99+ } else { return (

Slide 22

Slide 22 text

How Does React Transition BETWEEN STATES?

Slide 23

Slide 23 text

Comment Like Share Comment Like Share You like this.

Slide 24

Slide 24 text

React CALCULATES THE SMALLEST SET OF CHANGES TO MAKE TO THE UI.

Slide 25

Slide 25 text

“LIKE” -> “LIKE” INSERT “YOU LIKE THIS” Comment Share You like this. Like Like

Slide 26

Slide 26 text

Some React Native Code

Slide 27

Slide 27 text

var Toggle = React.createClass({ getInitialState: function() { return {on: false}; }, handlePress: function(event) { this.setState({on: !this.state.on}); }, render: function() { var text = this.state.on ? 'Toggle on' : 'Toggle off'; return ( {text} ); } });

Slide 28

Slide 28 text

new ViewGroup(getContext()) new TextView(getContext()) new ImageView(getContext())

Slide 29

Slide 29 text

How it works (Thanks Andy)

Slide 30

Slide 30 text

Architecture • A set of native modules (java) and a set of JS modules call methods on each other over a bridge • module: an object with some state and a collection of methods that can be called • bridge: the glue that facilitates these calls back and forth

Slide 31

Slide 31 text

• Async • Batched • Serialized method calls Native sends a single JS call… …JS executes it and responds with a list of native calls Native JS Executor JSC via C++ bindings (shipped in APK) Java/C++ via JNI BRIDGE (C++/Java)

Slide 32

Slide 32 text

Serialized communication 1. UIManager   1. createView   2. updateProperties   2. Networking   1. sendRequest   3. Storage   1. get   2. set   3. delete UIManager.createView(‘Text’,  {‘foo’:  ‘bar’});   [1,  1,  [‘Text’,  {‘foo’:  ‘bar’}]] Storage.set(‘key’,  ‘value’);   [3,  2,  [‘key’,  ‘value’]]

Slide 33

Slide 33 text

AppRegistry.runApplication(   ‘MyApp’,   new  WritableMap()); require(‘AppRegistry’).runApplication(‘MyApp’,  {}); UIManager.createView(2,  ’View’,  {…}); UIManager.createView(3,  ’Text’,  {…}); UIManager.createView(4,  ’View’,  {…}); … UIManagerModule#createView(2,  ‘View’,  …)   View  newView  =  new  View();   UIManagerModule#createView(3,  ‘Text’,  …)   TextView  newView  =  new  TextView();   UIManagerModule#createView(4,  ‘View’,  …)   View  newView  =  new  View();   … BRIDGE [1, 1, [‘MyApp’, {}]] [[2, 3, [2, ‘View’, {…}]], [2, 3, [3, ‘Text’, {…}]], [2, 3, [4, ‘View’, {…}]]] Java JS

Slide 34

Slide 34 text

Threading Model • Three threads: UI (app main thread), native modules, JS • Each runs an Android Looper (event loop) and processes a queue of Runnable events • Runnables execute within an error boundary so that native Exceptions redbox instead of hard crashing

Slide 35

Slide 35 text

Handle Timer Handle Timer Timer Fires Timer Fires UI Event Queue Native Modules Event Queue JS Event Queue Unrelated JS Operation 1 Unrelated JS Operation 2 Unrelated Native Operation 1 Unrelated Native Operation 2 Unrelated Native Operation 3 Dispatch View Updates Update UI Unrelated Native Operation 1 Unrelated Native Operation 2 Unrelated Native Operation 3 Unrelated JS Operation 1 Unrelated JS Operation 2 Dispatch View Updates Update UI

Slide 36

Slide 36 text

Why it might be useful to an Android developer

Slide 37

Slide 37 text

Iterating is fast

Slide 38

Slide 38 text

Instant Reload

Slide 39

Slide 39 text

Now for images too!

Slide 40

Slide 40 text

Write for iOS with the same tools

Slide 41

Slide 41 text

85% of code shared Ads Manager App

Slide 42

Slide 42 text

Standard tools for debugging too

Slide 43

Slide 43 text

Access built-in Android components

Slide 44

Slide 44 text

1 RIPPLE 2 OVERSCROLL 3 PULL TO REFRESH 4 DRAWER

Slide 45

Slide 45 text

Create custom modules

Slide 46

Slide 46 text

Example: Toast

Slide 47

Slide 47 text

public class ToastModule extends ReactContextBaseJavaModule { public ToastModule(ReactApplicationContext reactContext) { super(reactContext); } }

Slide 48

Slide 48 text

public class ToastModule extends ReactContextBaseJavaModule { public ToastModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "ToastAndroid"; } }

Slide 49

Slide 49 text

public class ToastModule extends ReactContextBaseJavaModule { public ToastModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "ToastAndroid"; } @ReactMethod public void show(String message, int duration) { Toast.makeText(getReactApplicationContext(), message, duration).show(); } }

Slide 50

Slide 50 text

public class ToastModule extends ReactContextBaseJavaModule { private static final String DURATION_SHORT_KEY = "SHORT"; private static final String DURATION_LONG_KEY = "LONG"; public ToastModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "ToastAndroid"; } @Override public Map getConstants() { final Map constants = MapBuilder.newHashMap(); constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT); constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG); return constants; } @ReactMethod public void show(String message, int duration) { Toast.makeText(getReactApplicationContext(), message, duration).show(); } }

Slide 51

Slide 51 text

var { NativeModules } = require('react-native'); var ToastAndroid = NativeModules.ToastAndroid; ToastAndroid.show('Awesome', ToastAndroid.SHORT); From JS…

Slide 52

Slide 52 text

And custom UI components

Slide 53

Slide 53 text

Example: Image

Slide 54

Slide 54 text

public class ReactImageManager extends SimpleViewManager { @Override public String getName() { return "RCTImageView"; } }

Slide 55

Slide 55 text

public class ReactImageManager extends SimpleViewManager { @Override public String getName() { return "RCTImageView"; } @Override public ReactImageView createViewInstance(ThemedReactContext context) { return new ReactImageView(context, Fresco.newDraweeControllerBuilder(), mCallerContext); } }

Slide 56

Slide 56 text

public class ReactImageManager extends SimpleViewManager { @Override public String getName() { return "RCTImageView"; } @Override public ReactImageView createViewInstance(ThemedReactContext context) { return new ReactImageView(context, Fresco.newDraweeControllerBuilder(), mCallerContext); } @ReactProp(name = "src") public void setSrc(ReactImageView view, @Nullable String src) { view.setSource(src); } @ReactProp(name = "borderRadius", defaultFloat = 0f) public void setBorderRadius(ReactImageView view, float borderRadius) { view.setBorderRadius(borderRadius); } @ReactProp(name = ViewProps.RESIZE_MODE) public void setResizeMode(ReactImageView view, @Nullable String resizeMode) { view.setScaleType(ImageResizeMode.toScaleType(resizeMode)); } }

Slide 57

Slide 57 text

Write simple, easy to maintain code!

Slide 58

Slide 58 text

816 lines, 20 files 241 lines, 4 files

Slide 59

Slide 59 text

So…

Slide 60

Slide 60 text

React Native • Try it out • Build an app • Submit issues and pull requests

Slide 61

Slide 61 text

Thank you! http://facebook.github.io/react-native/