Files
react-native/docs/native-modules-android.html
T
2015-12-16 00:32:36 +00:00

186 lines
51 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><title>Native Modules React Native | A framework for building native apps using React</title><meta name="viewport" content="width=device-width"><meta property="og:title" content="Native Modules React Native | A framework for building native apps using React"><meta property="og:type" content="website"><meta property="og:url" content="http://facebook.github.io/react-native/index.html"><meta property="og:image" content="http://facebook.github.io/react-native/img/opengraph.png?2"><meta property="og:description" content="A framework for building native apps using React"><link rel="shortcut icon" href="/react-native/img/favicon.png?2"><link rel="stylesheet" href="/react-native/css/react-native.css"><script type="text/javascript" src="//use.typekit.net/vqa1hcx.js"></script><script type="text/javascript">try{Typekit.load();}catch(e){}</script></head><body><div class="container"><div class="nav-main"><div class="wrap"><a class="nav-home" href="/react-native/"><img src="/react-native/img/header_logo.png">React Native</a><div class="nav-site-wrapper"><ul class="nav-site nav-site-internal"><li><a href="/react-native/docs/getting-started.html" class="active">Docs</a></li><li><a href="/react-native/support.html" class="">Support</a></li><li><a href="https://github.com/facebook/react-native/releases" class="">Releases</a></li><li><a href="http://reactnative.cc" class="">Newsletter</a></li><li><a href="/react-native/showcase.html" class="">Showcase</a></li></ul><ul class="nav-site nav-site-external"><li><a href="https://github.com/facebook/react-native" class="">GitHub</a></li><li><a href="http://facebook.github.io/react" class="">React</a></li></ul></div></div></div><section class="content wrap documentationContent"><div class="nav-docs"><div class="nav-docs-section"><h3>Quick Start</h3><ul><li><a style="margin-left:0;" class="" href="/react-native/docs/getting-started.html#content">Getting Started</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/android-setup.html#content">Android Setup</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/linux-windows-support.html#content">Linux and Windows Support</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/tutorial.html#content">Tutorial</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/videos.html#content">Videos</a></li></ul></div><div class="nav-docs-section"><h3>Guides</h3><ul><li><a style="margin-left:0;" class="" href="/react-native/docs/style.html#content">Style</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/images.html#content">Images</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/gesture-responder-system.html#content">Gesture Responder System</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/animations.html#content">Animations</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/accessibility.html#content">Accessibility</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/direct-manipulation.html#content">Direct Manipulation</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/debugging.html#content">Debugging</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/testing.html#content">Testing</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/javascript-environment.html#content">JavaScript Environment</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/navigator-comparison.html#content">Navigator Comparison</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/known-issues.html#content">Known Issues</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/performance.html#content">Performance</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/upgrading.html#content">Upgrading</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/platform-specific-code.html#content">Platform Specific Code</a></li></ul></div><div class="nav-docs-section"><h3>Guides (iOS)</h3><ul><li><a style="margin-left:0;" class="" href="/react-native/docs/native-modules-ios.html#content">Native Modules</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/native-components-ios.html#content">Native UI Components</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/linking-libraries-ios.html#content">Linking Libraries</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/running-on-device-ios.html#content">Running On Device</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/embedded-app-ios.html#content">Integrating with Existing Apps</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/communication-ios.html#content">Communication between native and React Native</a></li></ul></div><div class="nav-docs-section"><h3>Guides (Android)</h3><ul><li><a style="margin-left:0;" class="active" href="/react-native/docs/native-modules-android.html#content">Native Modules</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/native-components-android.html#content">Native UI Components</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/running-on-device-android.html#content">Running On Device</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/embedded-app-android.html#content">Integrating with Existing Apps</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/signed-apk-android.html#content">Generating Signed APK</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/android-ui-performance.html#content">Profiling Android UI Performance</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/android-building-from-source.html#content">Building React Native from source</a></li></ul></div><div class="nav-docs-section"><h3>components</h3><ul><li><a style="margin-left:0;" class="" href="/react-native/docs/activityindicatorios.html#content">ActivityIndicatorIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/datepickerios.html#content">DatePickerIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/drawerlayoutandroid.html#content">DrawerLayoutAndroid</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/image.html#content">Image</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/listview.html#content">ListView</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/mapview.html#content">MapView</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/modal.html#content">Modal</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/navigator.html#content">Navigator</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/navigatorios.html#content">NavigatorIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/pickerios.html#content">PickerIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/progressbarandroid.html#content">ProgressBarAndroid</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/progressviewios.html#content">ProgressViewIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/pulltorefreshviewandroid.html#content">PullToRefreshViewAndroid</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/scrollview.html#content">ScrollView</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/segmentedcontrolios.html#content">SegmentedControlIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/sliderios.html#content">SliderIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/switchandroid.html#content">SwitchAndroid</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/switchios.html#content">SwitchIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/tabbarios.html#content">TabBarIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/tabbarios-item.html#content">TabBarIOS.Item</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/text.html#content">Text</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/textinput.html#content">TextInput</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/toolbarandroid.html#content">ToolbarAndroid</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/touchablehighlight.html#content">TouchableHighlight</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/touchablenativefeedback.html#content">TouchableNativeFeedback</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/touchableopacity.html#content">TouchableOpacity</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/touchablewithoutfeedback.html#content">TouchableWithoutFeedback</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/view.html#content">View</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/viewpagerandroid.html#content">ViewPagerAndroid</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/webview.html#content">WebView</a></li></ul></div><div class="nav-docs-section"><h3>apis</h3><ul><li><a style="margin-left:0;" class="" href="/react-native/docs/actionsheetios.html#content">ActionSheetIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/alertios.html#content">AlertIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/animated.html#content">Animated</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/appregistry.html#content">AppRegistry</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/appstateios.html#content">AppStateIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/asyncstorage.html#content">AsyncStorage</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/backandroid.html#content">BackAndroid</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/cameraroll.html#content">CameraRoll</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/dimensions.html#content">Dimensions</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/intentandroid.html#content">IntentAndroid</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/interactionmanager.html#content">InteractionManager</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/layoutanimation.html#content">LayoutAnimation</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/linkingios.html#content">LinkingIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/nativemethodsmixin.html#content">NativeMethodsMixin</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/netinfo.html#content">NetInfo</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/panresponder.html#content">PanResponder</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/pixelratio.html#content">PixelRatio</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/pushnotificationios.html#content">PushNotificationIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/statusbarios.html#content">StatusBarIOS</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/stylesheet.html#content">StyleSheet</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/toastandroid.html#content">ToastAndroid</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/vibrationios.html#content">VibrationIOS</a></li></ul></div><div class="nav-docs-section"><h3>Polyfills</h3><ul><li><a style="margin-left:0;" class="" href="/react-native/docs/flexbox.html#content">Flexbox</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/geolocation.html#content">Geolocation</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/network.html#content">Network</a></li><li><a style="margin-left:0;" class="" href="/react-native/docs/timers.html#content">Timers</a></li></ul></div></div><div class="inner-content"><a id="content"></a><h1>Native Modules</h1><div><p>Sometimes an app needs access to a platform API that React Native doesn&#x27;t have a corresponding module for yet. Maybe you want to reuse some existing Java code without having to reimplement it in JavaScript, or write some high performance, multi-threaded code such as for image processing, a database, or any number of advanced extensions.</p><p>We designed React Native such that it is possible for you to write real native code and have access to the full power of the platform. This is a more advanced feature and we don&#x27;t expect it to be part of the usual development process, however it is essential that it exists. If React Native doesn&#x27;t support a native feature that you need, you should be able to build it yourself.</p><h2><a class="anchor" name="the-toast-module"></a>The Toast Module <a class="hash-link" href="#the-toast-module">#</a></h2><p>This guide will use the <a href="http://developer.android.com/reference/android/widget/Toast.html" target="_blank">Toast</a> example. Let&#x27;s say we would like to be able to create a toast message from JavaScript.</p><p>We start by creating a native module. A native module is a Java class that usually extends the <code>ReactContextBaseJavaModule</code> class and implements the functionality required by the JavaScript. Our goal here is to be able to write <code>ToastAndroid.show(&#x27;Awesome&#x27;, ToastAndroid.SHORT);</code> from JavaScript to display a short toast on the screen.</p><div class="prism language-javascript">package com<span class="token punctuation">.</span>facebook<span class="token punctuation">.</span>react<span class="token punctuation">.</span>modules<span class="token punctuation">.</span>toast<span class="token punctuation">;</span>
import android<span class="token punctuation">.</span>widget<span class="token punctuation">.</span>Toast<span class="token punctuation">;</span>
import com<span class="token punctuation">.</span>facebook<span class="token punctuation">.</span>react<span class="token punctuation">.</span>bridge<span class="token punctuation">.</span>NativeModule<span class="token punctuation">;</span>
import com<span class="token punctuation">.</span>facebook<span class="token punctuation">.</span>react<span class="token punctuation">.</span>bridge<span class="token punctuation">.</span>ReactApplicationContext<span class="token punctuation">;</span>
import com<span class="token punctuation">.</span>facebook<span class="token punctuation">.</span>react<span class="token punctuation">.</span>bridge<span class="token punctuation">.</span>ReactContext<span class="token punctuation">;</span>
import com<span class="token punctuation">.</span>facebook<span class="token punctuation">.</span>react<span class="token punctuation">.</span>bridge<span class="token punctuation">.</span>ReactContextBaseJavaModule<span class="token punctuation">;</span>
import com<span class="token punctuation">.</span>facebook<span class="token punctuation">.</span>react<span class="token punctuation">.</span>bridge<span class="token punctuation">.</span>ReactMethod<span class="token punctuation">;</span>
import java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>Map<span class="token punctuation">;</span>
public class <span class="token class-name">ToastModule</span> extends <span class="token class-name">ReactContextBaseJavaModule</span> <span class="token punctuation">{</span>
private static final String DURATION_SHORT_KEY <span class="token operator">=</span> <span class="token string">&quot;SHORT&quot;</span><span class="token punctuation">;</span>
private static final String DURATION_LONG_KEY <span class="token operator">=</span> <span class="token string">&quot;LONG&quot;</span><span class="token punctuation">;</span>
public <span class="token function">ToastModule<span class="token punctuation">(</span></span>ReactApplicationContext reactContext<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">super<span class="token punctuation">(</span></span>reactContext<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></div><p><code>ReactContextBaseJavaModule</code> requires that a method called <code>getName</code> is implemented. The purpose of this method is to return the string name of the <code>NativeModule</code> which represents this class in JavaScript. So here we will call this <code>ToastAndroid</code> so that we can access it through <code>React.NativeModules.ToastAndroid</code> in JavaScript.</p><div class="prism language-javascript"> @Override
public String <span class="token function">getName<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token string">&quot;ToastAndroid&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></div><p>An optional method called <code>getConstants</code> returns the constant values exposed to JavaScript. Its implementation is not required but is very useful to key pre-defined values that need to be communicated from JavaScript to Java in sync.</p><div class="prism language-javascript"> @Override
public Map&lt;String<span class="token punctuation">,</span> Object<span class="token operator">&gt;</span> <span class="token function">getConstants<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
final Map&lt;String<span class="token punctuation">,</span> Object<span class="token operator">&gt;</span> constants <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span>&lt;<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
constants<span class="token punctuation">.</span><span class="token function">put<span class="token punctuation">(</span></span>DURATION_SHORT_KEY<span class="token punctuation">,</span> Toast<span class="token punctuation">.</span>LENGTH_SHORT<span class="token punctuation">)</span><span class="token punctuation">;</span>
constants<span class="token punctuation">.</span><span class="token function">put<span class="token punctuation">(</span></span>DURATION_LONG_KEY<span class="token punctuation">,</span> Toast<span class="token punctuation">.</span>LENGTH_LONG<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> constants<span class="token punctuation">;</span>
<span class="token punctuation">}</span></div><p>To expose a method to JavaScript a Java method must be annotated using <code>@ReactMethod</code>. The return type of bridge methods is always <code>void</code>. React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events (see below).</p><div class="prism language-javascript"> @ReactMethod
public void <span class="token function">show<span class="token punctuation">(</span></span>String message<span class="token punctuation">,</span> int duration<span class="token punctuation">)</span> <span class="token punctuation">{</span>
Toast<span class="token punctuation">.</span><span class="token function">makeText<span class="token punctuation">(</span></span><span class="token function">getReactApplicationContext<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">,</span> message<span class="token punctuation">,</span> duration<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">show<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></div><h3><a class="anchor" name="argument-types"></a>Argument Types <a class="hash-link" href="#argument-types">#</a></h3><p>The following argument types are supported for methods annotated with <code>@ReactMethod</code> and they directly map to their JavaScript equivalents</p><div class="prism language-javascript">Boolean <span class="token operator">-</span><span class="token operator">&gt;</span> Bool
Integer <span class="token operator">-</span><span class="token operator">&gt;</span> Number
Double <span class="token operator">-</span><span class="token operator">&gt;</span> Number
Float <span class="token operator">-</span><span class="token operator">&gt;</span> Number
String <span class="token operator">-</span><span class="token operator">&gt;</span> String
Callback <span class="token operator">-</span><span class="token operator">&gt;</span> <span class="token keyword">function</span>
ReadableMap <span class="token operator">-</span><span class="token operator">&gt;</span> Object
ReadableArray <span class="token operator">-</span><span class="token operator">&gt;</span> Array</div><p>Read more about <a href="https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.java" target="_blank">ReadableMap</a> and <a href="https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableArray.java" target="_blank">ReadableArray</a></p><h3><a class="anchor" name="register-the-module"></a>Register the Module <a class="hash-link" href="#register-the-module">#</a></h3><p>The last step within Java is to register the Module; this happens in the <code>createNativeModules</code> of your apps package. If a module is not registered it will not be available from JavaScript.</p><div class="prism language-javascript">class <span class="token class-name">AnExampleReactPackage</span> implements <span class="token class-name">ReactPackage</span> <span class="token punctuation">{</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
@Override
public List&lt;NativeModule<span class="token operator">&gt;</span> <span class="token function">createNativeModules<span class="token punctuation">(</span></span>
ReactApplicationContext reactContext<span class="token punctuation">)</span> <span class="token punctuation">{</span>
List&lt;NativeModule<span class="token operator">&gt;</span> modules <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span>&lt;<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
modules<span class="token punctuation">.</span><span class="token function">add<span class="token punctuation">(</span></span><span class="token keyword">new</span> <span class="token class-name">ToastModule</span><span class="token punctuation">(</span>reactContext<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> modules<span class="token punctuation">;</span>
<span class="token punctuation">}</span></div><p>The package needs to be provided to the <strong>ReactInstanceManager</strong> when it is built. To accomplish this you will need to insert an <code>.addPackage(new YourPackageName())</code> call to the <code>mReactInstanceManager = ReactInstanceManager.builder()</code> call chain.</p><p>Refer to the code below and add the <code>addPackage</code> statement to your application&#x27;s <code>MainActivity.java</code> file. This file exists under the android folder in your react-native application directory. The path to this file is: <code>android/app/src/main/java/com/your-app-name/MainActivity.java</code>.</p><div class="prism language-javascript">mReactInstanceManager <span class="token operator">=</span> ReactInstanceManager<span class="token punctuation">.</span><span class="token function">builder<span class="token punctuation">(</span></span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">setApplication<span class="token punctuation">(</span></span><span class="token function">getApplication<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">setBundleAssetName<span class="token punctuation">(</span></span><span class="token string">&quot;AnExampleApp.android.bundle&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">setJSMainModuleName<span class="token punctuation">(</span></span><span class="token string">&quot;Examples/AnExampleApp/AnExampleApp.android&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">addPackage<span class="token punctuation">(</span></span><span class="token keyword">new</span> <span class="token class-name">AnExampleReactPackage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true"> // &lt;-- Add this line with your package name.
</span> <span class="token punctuation">.</span><span class="token function">setUseDeveloperSupport<span class="token punctuation">(</span></span><span class="token boolean">true</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">setInitialLifecycleState<span class="token punctuation">(</span></span>LifecycleState<span class="token punctuation">.</span>RESUMED<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">build<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></div><p>To make it simpler to access your new functionality from JavaScript, it is common to wrap the native module in a JavaScript module. This is not necessary but saves the consumers of your library the need to pull it off of <code>NativeModules</code> each time. This JavaScript file also becomes a good location for you to add any JavaScript side functionality.</p><div class="prism language-javascript"><span class="token string">&#x27;use strict&#x27;</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">/**
* This exposes the native ToastAndroid module as a JS module. This has a function &#x27;show&#x27;
* which takes the following parameters:
*
* 1. String message: A string with the text to toast
* 2. int duration: The duration of the toast. May be ToastAndroid.SHORT or ToastAndroid.LONG
*/</span>
<span class="token keyword">var</span> <span class="token punctuation">{</span> NativeModules <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require<span class="token punctuation">(</span></span><span class="token string">&#x27;react-native&#x27;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> NativeModules<span class="token punctuation">.</span>ToastAndroid<span class="token punctuation">;</span></div><p>Now, from your other JavaScript file you can call the method like this:</p><div class="prism language-javascript"><span class="token keyword">var</span> ToastAndroid <span class="token operator">=</span> <span class="token function">require<span class="token punctuation">(</span></span><span class="token string">&#x27;./ToastAndroid&#x27;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
ToastAndroid<span class="token punctuation">.</span><span class="token function">show<span class="token punctuation">(</span></span><span class="token string">&#x27;Awesome&#x27;</span><span class="token punctuation">,</span> ToastAndroid<span class="token punctuation">.</span>SHORT<span class="token punctuation">)</span><span class="token punctuation">;</span></div><h2><a class="anchor" name="beyond-toasts"></a>Beyond Toasts <a class="hash-link" href="#beyond-toasts">#</a></h2><h3><a class="anchor" name="callbacks"></a>Callbacks <a class="hash-link" href="#callbacks">#</a></h3><p>Native modules also support a special kind of argument - a callback. In most cases it is used to provide the function call result to JavaScript.</p><div class="prism language-javascript">public class <span class="token class-name">UIManagerModule</span> extends <span class="token class-name">ReactContextBaseJavaModule</span> <span class="token punctuation">{</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
@ReactMethod
public void <span class="token function">measureLayout<span class="token punctuation">(</span></span>
int tag<span class="token punctuation">,</span>
int ancestorTag<span class="token punctuation">,</span>
Callback errorCallback<span class="token punctuation">,</span>
Callback successCallback<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token function">measureLayout<span class="token punctuation">(</span></span>tag<span class="token punctuation">,</span> ancestorTag<span class="token punctuation">,</span> mMeasureBuffer<span class="token punctuation">)</span><span class="token punctuation">;</span>
float relativeX <span class="token operator">=</span> PixelUtil<span class="token punctuation">.</span><span class="token function">toDIPFromPixel<span class="token punctuation">(</span></span>mMeasureBuffer<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
float relativeY <span class="token operator">=</span> PixelUtil<span class="token punctuation">.</span><span class="token function">toDIPFromPixel<span class="token punctuation">(</span></span>mMeasureBuffer<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
float width <span class="token operator">=</span> PixelUtil<span class="token punctuation">.</span><span class="token function">toDIPFromPixel<span class="token punctuation">(</span></span>mMeasureBuffer<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
float height <span class="token operator">=</span> PixelUtil<span class="token punctuation">.</span><span class="token function">toDIPFromPixel<span class="token punctuation">(</span></span>mMeasureBuffer<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
successCallback<span class="token punctuation">.</span><span class="token function">invoke<span class="token punctuation">(</span></span>relativeX<span class="token punctuation">,</span> relativeY<span class="token punctuation">,</span> width<span class="token punctuation">,</span> height<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">IllegalViewOperationException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
errorCallback<span class="token punctuation">.</span><span class="token function">invoke<span class="token punctuation">(</span></span>e<span class="token punctuation">.</span><span class="token function">getMessage<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span></div><p>This method would be accessed in JavaScript using:</p><div class="prism language-javascript">UIManager<span class="token punctuation">.</span><span class="token function">measureLayout<span class="token punctuation">(</span></span>
<span class="token number">100</span><span class="token punctuation">,</span>
<span class="token number">100</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span>msg<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log<span class="token punctuation">(</span></span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> width<span class="token punctuation">,</span> height<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log<span class="token punctuation">(</span></span>x <span class="token operator">+</span> <span class="token string">&#x27;:&#x27;</span> <span class="token operator">+</span> y <span class="token operator">+</span> <span class="token string">&#x27;:&#x27;</span> <span class="token operator">+</span> width <span class="token operator">+</span> <span class="token string">&#x27;:&#x27;</span> <span class="token operator">+</span> height<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span></div><p>A native module is supposed to invoke its callback only once. It can, however, store the callback and invoke it later.</p><p>It is very important to highlight that the callback is not invoked immediately after the native function completes - remember that bridge communication is asynchronous, and this too is tied to the run loop.</p><h3><a class="anchor" name="promises"></a>Promises <a class="hash-link" href="#promises">#</a></h3><p>Native modules can also fulfill a promise, which can simplify your code, especially when using ES2016&#x27;s <code>async/await</code> syntax. When the last parameter of a bridged native method is a <code>Promise</code>, its corresponding JS method will return a JS Promise object.</p><p>Refactoring the above code to use a promise instead of callbacks looks like this:</p><div class="prism language-javascript">public class <span class="token class-name">UIManagerModule</span> extends <span class="token class-name">ReactContextBaseJavaModule</span> <span class="token punctuation">{</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
@ReactMethod
public void <span class="token function">measureLayout<span class="token punctuation">(</span></span>
int tag<span class="token punctuation">,</span>
int ancestorTag<span class="token punctuation">,</span>
Promise promise<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token function">measureLayout<span class="token punctuation">(</span></span>tag<span class="token punctuation">,</span> ancestorTag<span class="token punctuation">,</span> mMeasureBuffer<span class="token punctuation">)</span><span class="token punctuation">;</span>
WritableMap map <span class="token operator">=</span> Arguments<span class="token punctuation">.</span><span class="token function">createMap<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
map<span class="token punctuation">.</span><span class="token function">putDouble<span class="token punctuation">(</span></span><span class="token string">&quot;relativeX&quot;</span><span class="token punctuation">,</span> PixelUtil<span class="token punctuation">.</span><span class="token function">toDIPFromPixel<span class="token punctuation">(</span></span>mMeasureBuffer<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
map<span class="token punctuation">.</span><span class="token function">putDouble<span class="token punctuation">(</span></span><span class="token string">&quot;relativeY&quot;</span><span class="token punctuation">,</span> PixelUtil<span class="token punctuation">.</span><span class="token function">toDIPFromPixel<span class="token punctuation">(</span></span>mMeasureBuffer<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
map<span class="token punctuation">.</span><span class="token function">putDouble<span class="token punctuation">(</span></span><span class="token string">&quot;width&quot;</span><span class="token punctuation">,</span> PixelUtil<span class="token punctuation">.</span><span class="token function">toDIPFromPixel<span class="token punctuation">(</span></span>mMeasureBuffer<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
map<span class="token punctuation">.</span><span class="token function">putDouble<span class="token punctuation">(</span></span><span class="token string">&quot;height&quot;</span><span class="token punctuation">,</span> PixelUtil<span class="token punctuation">.</span><span class="token function">toDIPFromPixel<span class="token punctuation">(</span></span>mMeasureBuffer<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
promise<span class="token punctuation">.</span><span class="token function">resolve<span class="token punctuation">(</span></span>map<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">IllegalViewOperationException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
promise<span class="token punctuation">.</span><span class="token function">reject<span class="token punctuation">(</span></span>e<span class="token punctuation">.</span><span class="token function">getMessage<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span></div><p>The JavaScript counterpart of this method returns a Promise. This means you can use the <code>await</code> keyword within an async function to call it and wait for its result:</p><div class="prism language-javascript">async <span class="token keyword">function</span> <span class="token function">measureLayout<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token keyword">var</span> <span class="token punctuation">{</span>
relativeX<span class="token punctuation">,</span>
relativeY<span class="token punctuation">,</span>
width<span class="token punctuation">,</span>
height<span class="token punctuation">,</span>
<span class="token punctuation">}</span> <span class="token operator">=</span> await UIManager<span class="token punctuation">.</span><span class="token function">measureLayout<span class="token punctuation">(</span></span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log<span class="token punctuation">(</span></span>relativeX <span class="token operator">+</span> <span class="token string">&#x27;:&#x27;</span> <span class="token operator">+</span> relativeY <span class="token operator">+</span> <span class="token string">&#x27;:&#x27;</span> <span class="token operator">+</span> width <span class="token operator">+</span> <span class="token string">&#x27;:&#x27;</span> <span class="token operator">+</span> height<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">error<span class="token punctuation">(</span></span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token function">measureLayout<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></div><h3><a class="anchor" name="threading"></a>Threading <a class="hash-link" href="#threading">#</a></h3><p>Native modules should not have any assumptions about what thread they are being called on, as the current assignment is subject to change in the future. If a blocking call is required, the heavy work should be dispatched to an internally managed worker thread, and any callbacks distributed from there.</p><h3><a class="anchor" name="sending-events-to-javascript"></a>Sending Events to JavaScript <a class="hash-link" href="#sending-events-to-javascript">#</a></h3><p>Native modules can signal events to JavaScript without being invoked directly. The easiest way to do this is to use the <code>RCTDeviceEventEmitter</code> which can be obtained from the <code>ReactContext</code> as in the code snippet below.</p><div class="prism language-javascript"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
private void <span class="token function">sendEvent<span class="token punctuation">(</span></span>ReactContext reactContext<span class="token punctuation">,</span>
String eventName<span class="token punctuation">,</span>
@Nullable WritableMap params<span class="token punctuation">)</span> <span class="token punctuation">{</span>
reactContext
<span class="token punctuation">.</span><span class="token function">getJSModule<span class="token punctuation">(</span></span>DeviceEventManagerModule<span class="token punctuation">.</span>RCTDeviceEventEmitter<span class="token punctuation">.</span>class<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">emit<span class="token punctuation">(</span></span>eventName<span class="token punctuation">,</span> params<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
WritableMap params <span class="token operator">=</span> Arguments<span class="token punctuation">.</span><span class="token function">createMap<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token function">sendEvent<span class="token punctuation">(</span></span>reactContext<span class="token punctuation">,</span> <span class="token string">&quot;keyboardWillShow&quot;</span><span class="token punctuation">,</span> params<span class="token punctuation">)</span><span class="token punctuation">;</span></div><p>JavaScript modules can then register to receive events by <code>addListenerOn</code> using the <code>Subscribable</code> mixin</p><div class="prism language-javascript"><span class="token keyword">var</span> <span class="token punctuation">{</span> DeviceEventEmitter <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require<span class="token punctuation">(</span></span><span class="token string">&#x27;react-native&#x27;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token keyword">var</span> ScrollResponderMixin <span class="token operator">=</span> <span class="token punctuation">{</span>
mixins<span class="token punctuation">:</span> <span class="token punctuation">[</span>Subscribable<span class="token punctuation">.</span>Mixin<span class="token punctuation">]</span><span class="token punctuation">,</span>
componentWillMount<span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">addListenerOn<span class="token punctuation">(</span></span>DeviceEventEmitter<span class="token punctuation">,</span>
<span class="token string">&#x27;keyboardWillShow&#x27;</span><span class="token punctuation">,</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>scrollResponderKeyboardWillShow<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
scrollResponderKeyboardWillShow<span class="token punctuation">:</span><span class="token keyword">function</span><span class="token punctuation">(</span>e<span class="token punctuation">:</span> Event<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>keyboardWillOpenTo <span class="token operator">=</span> e<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>onKeyboardWillShow &amp;&amp; <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span><span class="token function">onKeyboardWillShow<span class="token punctuation">(</span></span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span></div><p>You can also directly use the <code>DeviceEventEmitter</code> module to listen for events.</p><div class="prism language-javascript"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
componentWillMount<span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
DeviceEventEmitter<span class="token punctuation">.</span><span class="token function">addListener<span class="token punctuation">(</span></span><span class="token string">&#x27;keyboardWillShow&#x27;</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span>e<span class="token punctuation">:</span> Event<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // handle event.
</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span></div></div><div class="docs-prevnext"><a class="docs-next" href="native-components-android.html#content">Next →</a></div></div></section><footer class="wrap"><div class="center">© 2015 Facebook Inc.</div></footer></div><div id="fb-root"></div><script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-41298772-2', 'facebook.github.io');
ga('send', 'pageview');
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)
){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
</script><script src="/react-native/js/scripts.js"></script></body></html>