More Related Content
Similar to React Native Androidはなぜ動くのか
Similar to React Native Androidはなぜ動くのか(20)
More from Yukiya Nakagawa
More from Yukiya Nakagawa(20)
React Native Androidはなぜ動くのか
- 2. Who are you?
• Yukiya Nakagawa / @Nkzn
• @
•
• Android 2009
• React Native v0.17
- 20. import React from 'react';
import ReactDOM from 'react-dom';
const styles = {
container: {display: 'flex', flexDirection: ‘row', …}
};
class App extends React.Component {
render() {
const myName = /* props or state */;
return (
<div style={styles.container}>
<Header />
<LeftPane />
<RightPane
name={myName} />
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
- 31. import React from 'react';
import ReactDOM from 'react-dom';
const styles = {
container: {display: 'flex', flexDirection: ‘row', …}
};
class App extends React.Component {
render() {
const myName = /* props or state */;
return (
<div style={styles.container}>
<Header />
<LeftPane />
<RightPane
name={myName} />
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
import ReactDOM from 'react-dom';
div
div
ReactDOM.render(
<App />,
document.getElementById('app')
);
- 32. import React from "react";
import { View, AppRegistry } from "react-native";
const styles = {
container: {display: 'flex', flexDirection: ‘row', …}
};
class App extends React.Component {
render() {
const myName = /* props or state */;
return (
<View style={styles.container}>
<Header />
<LeftPane />
<RightPane
name={myName} />
</View>
);
}
}
AppRegistry.registerComponent(
"MyReactNativeApp",
() => App
);
- 53. @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(
mReactInstanceManager,
"MyReactNativeApp",
null);
setContentView(mReactRootView);
}
Java
Activity RN
- 54. @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(
mReactInstanceManager,
"MyReactNativeApp",
null);
setContentView(mReactRootView);
}
Java
ReactRootView FrameLayout
- 55. @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(
mReactInstanceManager,
"MyReactNativeApp",
null);
setContentView(mReactRootView);
}
Java
ReactInstanceManager
- 56. @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(
mReactInstanceManager,
"MyReactNativeApp",
null);
setContentView(mReactRootView);
}
Java
RootView InstanceManager
- 57. @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(
mReactInstanceManager,
"MyReactNativeApp",
null);
setContentView(mReactRootView);
}
Java
setContentView
- 58. import React from "react";
import { View, AppRegistry } from "react-native";
const styles = {
container: {display: 'flex', flexDirection: ‘row', …}
};
class App extends React.Component {
render() {
const myName = /* props or state */;
return (
<View style={styles.container}>
<Header />
<LeftPane />
<RightPane
name={myName} />
</View>
);
}
}
AppRegistry.registerComponent(
"MyReactNativeApp",
() => App
);
MyReactNativeApp
- 68. const ToastAndroid = require('ToastAndroid');
ToastAndroid.show(" ",
ToastAndroid.SHORT);
JS Toast
JS
- 69. @ReactModule(name = "ToastAndroid")
public class ToastModule
extends ReactContextBaseJavaModule {
@ReactMethod
public void show(final String message,
final int duration) {
UiThreadUtil.runOnUiThread(() -> {
Toast.makeText(
getReactApplicationContext(),
message,
duration).show();
});
}
}
Toast
Java
- 70. @ReactModule(name = "ToastAndroid")
public class ToastModule
extends ReactContextBaseJavaModule {
@ReactMethod
public void show(final String message,
final int duration) {
UiThreadUtil.runOnUiThread(() -> {
Toast.makeText(
getReactApplicationContext(),
message,
duration).show();
});
}
}
ReactContextBaseJavaModule
Java
- 71. @ReactModule(name = "ToastAndroid")
public class ToastModule
extends ReactContextBaseJavaModule {
@ReactMethod
public void show(final String message,
final int duration) {
UiThreadUtil.runOnUiThread(() -> {
Toast.makeText(
getReactApplicationContext(),
message,
duration).show();
});
}
}
Native Module
Java
※name
- 72. @ReactModule(name = "ToastAndroid")
public class ToastModule
extends ReactContextBaseJavaModule {
@ReactMethod
public void show(final String message,
final int duration) {
UiThreadUtil.runOnUiThread(() -> {
Toast.makeText(
getReactApplicationContext(),
message,
duration).show();
});
}
}
JS @ReactMethod
Java
- 73. @ReactModule(name = "ToastAndroid")
public class ToastModule
extends ReactContextBaseJavaModule {
@ReactMethod
public void show(final String message,
final int duration) {
UiThreadUtil.runOnUiThread(() -> {
Toast.makeText(
getReactApplicationContext(),
message,
duration).show();
});
}
}
Android not UI Thread
Java
- 76. public class ToastPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
new ToastModule(reactContext));
}
}
ReactPackage
Java
- 77. public class ToastPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
new ToastModule(reactContext));
}
}
ReactPackage
Java
- 78. public class ToastPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
new ToastModule(reactContext));
}
}
createNativeModules
Java
- 82. const ToastAndroid = require('ToastAndroid');
ToastAndroid.show(" ",
ToastAndroid.SHORT);
JavaScript
JS
- 86. + hasKey(name: String): boolean
+ isNull(name: String): boolean
+ getBoolean(name: String): boolean
+ getDouble(name: String): double
+ getInt(name: String): int
+ getString(name: String): String
+ getArray(name: String): ReadableArray
+ getMap(name: String): ReadableMap
+ getDynamic(name: String): Dynamic
+ getType(name: String): ReadableType
+ keySetIterator(): ReadableMapKeySetIterator
+ toHashMap(): HashMap<String, Object>
+ putNull(key: String)
+ putBoolean(key: String, value: boolean)
+ putDouble(key: String, value: double)
+ putInt(key: String, value: int)
+ putString(key: String, value: String)
+ putArray(key: String, value: WritableArray)
+ putMap(key: String, value: WritableMap)
+ merge(source: ReadableMap);
- 87. + size(index: int): int
+ isNull(index: int): boolean
+ getBoolean(index: int): boolean
+ getDouble(index: int): double
+ getInt(index: int): int
+ getString(index: int): String
+ getArray(index: int): ReadableArray
+ getMap(index: int): ReadableMap
+ getDynamic(index: int): Dynamic
+ getType(index: int): ReadableType
+ toArrayList(index: int): ArrayList<Object>
+ pushNull()
+ pushBoolean(value: boolean)
+ pushDouble(value: double)
+ pushInt(value: int)
+ pushString(value: String)
+ pushArray(array: WritableArray)
+ pushMap(map: WritableMap)
- 91. @ReactMethod
public void getString(Promise promise) {
try {
ClipboardManager clipboard = getClipboardService();
ClipData clipData = clipboard.getPrimaryClip();
if (clipData == null) {
promise.resolve("");
} else if (clipData.getItemCount() >= 1) {
ClipData.Item firstItem = clipboard
.getPrimaryClip()
.getItemAt(0);
promise.resolve("" + firstItem.getText());
} else {
promise.resolve("");
}
} catch (Exception e) {
promise.reject(e);
}
}
Clipboard#getString
Java
- 92. @ReactMethod
public void getString(Promise promise) {
try {
ClipboardManager clipboard = getClipboardService();
ClipData clipData = clipboard.getPrimaryClip();
if (clipData == null) {
promise.resolve("");
} else if (clipData.getItemCount() >= 1) {
ClipData.Item firstItem = clipboard
.getPrimaryClip()
.getItemAt(0);
promise.resolve("" + firstItem.getText());
} else {
promise.resolve("");
}
} catch (Exception e) {
promise.reject(e);
}
}
JS
RxJava
onNext, onError
※ Clipboard
Java
- 96. // JS
class RCTDeviceEventEmitter extends EventEmitter {
emit(eventType) {...}
addListener(eventType, listener, context) {...}
removeAllListeners(eventType) {...}
removeSubscription(subscription) {...}
}
JS
RCTDeviceEventEmitter.js
※ emit EventEmitter
- 98. // JS
public void emitHardwareBackPressed() {
getReactApplicationContext()
.getJSModule(RCTDeviceEventEmitter.class)
.emit("hardwareBackPress", null);
}
JS emit
Java
DeviceEventManagerModule.java
- 108. public class PhotoViewManager
extends SimpleViewManager<PhotoView> {
@Override
public String getName() {
return "PhotoView";
}
@Override
protected PhotoView createViewInstance(
ThemedReactContext reactContext) {
return new PhotoView(reactContext);
}
@ReactProp(name = "uri")
public void setUri(PhotoView view,
@Nullable String uri) {
view.setUri(uri);
}
}
React
Java
- 109. public class PhotoViewManager
extends SimpleViewManager<PhotoView> {
@Override
public String getName() {
return "PhotoView";
}
@Override
protected PhotoView createViewInstance(
ThemedReactContext reactContext) {
return new PhotoView(reactContext);
}
@ReactProp(name = "uri")
public void setUri(PhotoView view,
@Nullable String uri) {
view.setUri(uri);
}
}
SimpleViewManager
Java
- 110. public class PhotoViewManager
extends SimpleViewManager<PhotoView> {
@Override
public String getName() {
return "PhotoView";
}
@Override
protected PhotoView createViewInstance(
ThemedReactContext reactContext) {
return new PhotoView(reactContext);
}
@ReactProp(name = "uri")
public void setUri(PhotoView view,
@Nullable String uri) {
view.setUri(uri);
}
}
React
Java
- 111. public class PhotoViewManager
extends SimpleViewManager<PhotoView> {
@Override
public String getName() {
return "PhotoView";
}
@Override
protected PhotoView createViewInstance(
ThemedReactContext reactContext) {
return new PhotoView(reactContext);
}
@ReactProp(name = "uri")
public void setUri(PhotoView view,
@Nullable String uri) {
view.setUri(uri);
}
}
Android View
Java
- 112. public class PhotoViewManager
extends SimpleViewManager<PhotoView> {
@Override
public String getName() {
return "PhotoView";
}
@Override
protected PhotoView createViewInstance(
ThemedReactContext reactContext) {
return new PhotoView(reactContext);
}
@ReactProp(name = "uri")
public void setUri(PhotoView view,
@Nullable String uri) {
view.setUri(uri);
}
}
props
Java
- 113. //
@ReactProp(name = "uri")
public void setUri(PhotoView view,
@Nullable String uri) {
view.setUri(uri);
}
//
<PhotoView
uri="http://example.com/hoge.png" />
Java
JS
- 115. public class MyLibraryPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new PhotoViewManager()
);
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
ReactPackage
Java
- 116. public class MyLibraryPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new PhotoViewManager()
);
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
createViewManagers
Java
- 118. import PropTypes from “prop-types”;
import {
requireNativeComponent,
View
} from "react-native";
const name = "PhotoView";
const photoViewInterface = {
name: name,
displayName: name,
propTypes: {
...View.propTypes,
uri: PropTypes.string.isRequired
}
};
export default
requireNativeComponent(name, photoViewInterface);
JS PhotoView.js
JS
Java
Java
- 126. @ReactMethod
public void createView(
int tag,
String className,
int rootViewTag,
ReadableMap props) {
mUIImplementation.createView(
tag, className, rootViewTag, props);
}
@ReactMethod
public void updateView(
int tag,
String className,
ReadableMap props) {
mUIImplementation.updateView(
tag, className, props);
}
UIManagerModule.java
- 128. View
• React View Java
ReactShadowNode Java View
Yoga
• UIManagerModule React Java
View
• View View
- 132. • Java C++ JS
• ReactInstanceManager
• ReactInstanceManager Native
Module JavaScript Module
• UI Native Module