Files
react-native/docs/0.60/native-modules-android.html
2021-03-13 08:44:52 +00:00

102 lines
96 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="generator" content="Docusaurus v2.0.0-alpha.70">
<link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="React Native Blog RSS Feed">
<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="React Native Blog Atom Feed">
<link rel="preconnect" href="https://www.google-analytics.com">
<script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","UA-41298772-2","auto"),ga("send","pageview")</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
<link rel="preconnect" href="https://www.google-analytics.com">
<link rel="preconnect" href="https://www.googletagmanager.com">
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-41298772-2"></script>
<script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","UA-41298772-2",{})</script>
<link rel="search" type="application/opensearchdescription+xml" title="React Native" href="/opensearch.xml">
<link rel="icon" href="/img/pwa/manifest-icon-512.png">
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#20232a">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="#20232a">
<link rel="apple-touch-icon" href="/img/pwa/manifest-icon-512.png">
<link rel="mask-icon" href="/img/pwa/manifest-icon-512.png" color="#06bcee">
<meta name="msapplication-TileImage" href="/img/pwa/manifest-icon-512.png">
<meta name="msapplication-TileColor" content="#20232a">
<script src="https://cdn.jsdelivr.net/npm/focus-visible@5.2.0/dist/focus-visible.min.js" defer="defer"></script>
<script src="https://snack.expo.io/embed.js" defer="defer"></script><title data-react-helmet="true">Native Modules · React Native</title><meta data-react-helmet="true" name="twitter:image:alt" content="Image for React Native"><meta data-react-helmet="true" name="docsearch:language" content="en"><meta data-react-helmet="true" name="docsearch:version" content="0.60"><meta data-react-helmet="true" name="docsearch:docusaurus_tag" content="docs-default-0.60"><meta data-react-helmet="true" property="og:image" content="https://reactnative.dev/img/logo-og.png"><meta data-react-helmet="true" name="twitter:card" content="summary"><meta data-react-helmet="true" name="twitter:image" content="https://reactnative.dev/img/logo-og.png"><meta data-react-helmet="true" property="og:title" content="Native Modules · React Native"><meta data-react-helmet="true" name="description" content="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."><meta data-react-helmet="true" property="og:description" content="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."><meta data-react-helmet="true" property="og:url" content="https://reactnative.dev/docs/0.60/native-modules-android"><link data-react-helmet="true" rel="shortcut icon" href="/img/favicon.ico"><link data-react-helmet="true" rel="preconnect" href="https://BH4D9OD16A-dsn.algolia.net" crossorigin="anonymous"><link data-react-helmet="true" rel="canonical" href="https://reactnative.dev/docs/0.60/native-modules-android"><link rel="stylesheet" href="/styles.f56da522.css">
<link rel="stylesheet" href="/main.3de2b5ef.css">
<link rel="preload" href="/styles.9d29dd5a.js" as="script">
<link rel="preload" href="/runtime~main.b00a5634.js" as="script">
<link rel="preload" href="/main.4103a08e.js" as="script">
<link rel="preload" href="/1.7a6193e2.js" as="script">
<link rel="preload" href="/2.9b40dc51.js" as="script">
<link rel="preload" href="/1089.caa7a648.js" as="script">
<link rel="preload" href="/ae345423.7c9998ff.js" as="script">
<link rel="preload" href="/17896441.b54b3e3c.js" as="script">
<link rel="preload" href="/3720ec3a.03c72c47.js" as="script">
</head>
<body>
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus">
<nav aria-label="Skip navigation links"><button type="button" tabindex="0" class="skipToContent_3aLp">Skip to main content</button></nav><nav class="navbar navbar--fixed-top navbar--dark"><div class="navbar__inner"><div class="navbar__items"><div aria-label="Navigation bar toggle" class="navbar__toggle" role="button" tabindex="0"><svg aria-label="Menu" width="30" height="30" viewBox="0 0 30 30" role="img" focusable="false"><title>Menu</title><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></div><a class="navbar__brand" href="/"><img src="/img/header_logo.svg" alt="React Native" class="themedImage_phiS themedImage--light_VJaY navbar__logo"><img src="/img/header_logo.svg" alt="React Native" class="themedImage_phiS themedImage--dark_1NF3 navbar__logo"><strong class="navbar__title">React Native</strong></a><div class="navbar__item dropdown dropdown--hoverable dropdown--left"><a class="navbar__item navbar__link" href="/docs/0.60/getting-started">0.60</a><ul class="dropdown__menu"><li><a class="dropdown__link" href="/docs/next/native-modules-android">Next</a></li><li><a class="dropdown__link" href="/docs/native-modules-android">0.64</a></li><li><a class="dropdown__link" href="/docs/0.63/native-modules-android">0.63</a></li><li><a class="dropdown__link" href="/docs/0.62/native-modules-android">0.62</a></li><li><a class="dropdown__link" href="/docs/0.61/native-modules-android">0.61</a></li><li><a aria-current="page" class="dropdown__link dropdown__link--active" href="/docs/0.60/native-modules-android">0.60</a></li><li><a class="dropdown__link" href="/versions">All versions</a></li></ul></div></div><div class="navbar__items navbar__items--right"><a class="navbar__item navbar__link navbar__link--active" href="/docs/0.60/getting-started">Docs</a><a class="navbar__item navbar__link" href="/docs/0.60/components-and-apis">Components</a><a class="navbar__item navbar__link" href="/docs/0.60/accessibilityinfo">API</a><a class="navbar__item navbar__link" href="/help">Community</a><a class="navbar__item navbar__link" href="/blog">Blog</a><a href="https://github.com/facebook/react-native" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link navbar-github-link" aria-label="GitHub repository"></a><div class="react-toggle react-toggle--disabled displayOnlyInLargeViewport_Bh6k"><div class="react-toggle-track"><div class="react-toggle-track-check"><span class="toggle_1UDy">🌜</span></div><div class="react-toggle-track-x"><span class="toggle_1UDy">🌞</span></div></div><div class="react-toggle-thumb"></div><input type="checkbox" disabled="" aria-label="Dark mode toggle" class="react-toggle-screenreader-only"></div><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span></button></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div><div class="navbar-sidebar"><div class="navbar-sidebar__brand"><a class="navbar__brand" href="/"><img src="/img/header_logo.svg" alt="React Native" class="themedImage_phiS themedImage--light_VJaY navbar__logo"><img src="/img/header_logo.svg" alt="React Native" class="themedImage_phiS themedImage--dark_1NF3 navbar__logo"><strong class="navbar__title">React Native</strong></a></div><div class="navbar-sidebar__items"><div class="menu"><ul class="menu__list"><li class="menu__list-item"><a class="menu__link navbar__link--active" href="/docs/0.60/getting-started">Docs</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/0.60/components-and-apis">Components</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/0.60/accessibilityinfo">API</a></li><li class="menu__list-item"><a class="menu__link" href="/help">Community</a></li><li class="menu__list-item"><a class="menu__link" href="/blog">Blog</a></li><li class="menu__list-item"><a role="button" class="menu__link menu__link--sublist">Versions</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" href="/docs/next/native-modules-android">Next</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/native-modules-android">0.64</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/0.63/native-modules-android">0.63</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/0.62/native-modules-android">0.62</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/0.61/native-modules-android">0.61</a></li><li class="menu__list-item"><a aria-current="page" class="menu__link menu__link--active" href="/docs/0.60/native-modules-android">0.60</a></li><li class="menu__list-item"><a class="menu__link" href="/versions">All versions</a></li></ul></li><li class="menu__list-item"><a href="https://github.com/facebook/react-native" target="_blank" rel="noopener noreferrer" class="menu__link navbar-github-link" aria-label="GitHub repository"></a></li></ul></div></div></div></nav><div class="main-wrapper"><div class="docPage_1mVJ"><div class="docSidebarContainer_uPTz" role="complementary"><div class="sidebar_M-Lc"><div class="menu menu--responsive thin-scrollbar menu_tgpy"><button aria-label="Open Menu" aria-haspopup="true" class="button button--secondary button--sm menu__button" type="button"><svg aria-label="Menu" class="sidebarMenuIcon_1e05" width="24" height="24" viewBox="0 0 30 30" role="img" focusable="false"><title>Menu</title><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><ul class="menu__list"><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">The Basics</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/getting-started">Introduction</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/tutorial">Learn the Basics</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/style">Style</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/height-and-width">Height and Width</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/flexbox">Layout with Flexbox</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/handling-text-input">Handling Text Input</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/handling-touches">Handling Touches</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/using-a-scrollview">Using a ScrollView</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/using-a-listview">Using List Views</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/network">Networking</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/more-resources">More Resources</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Guides</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/platform-specific-code">Platform Specific Code</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/navigation">Navigating Between Screens</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/images">Images</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/animations">Animations</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/accessibility">Accessibility</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/improvingux">Improving User Experience</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/optimizing-flatlist-configuration">Optimizing Flatlist Configuration</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/timers">Timers</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/debugging">Debugging</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/performance">Performance</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/gesture-responder-system">Gesture Responder System</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/javascript-environment">JavaScript Environment</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/typescript">Using TypeScript with React Native</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/direct-manipulation">Direct Manipulation</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/colors">Color Reference</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/integration-with-existing-apps">Integration with Existing Apps</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/building-for-tv">Building For TV Devices</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/running-on-device">Running On Device</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/upgrading">Upgrading to new React Native versions</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/troubleshooting">Troubleshooting</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/native-modules-setup">Native Modules Setup</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/out-of-tree-platforms">Out-of-Tree Platforms</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Guides (iOS)</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/native-modules-ios">Native Modules</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/native-components-ios">Native UI Components</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/linking-libraries-ios">Linking Libraries</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/running-on-simulator-ios">Running On Simulator</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/communication-ios">Communication between native and React Native</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/0.60/app-extensions">App Extensions</a></li></ul></li><li class="menu__list-item"><a class="menu__link menu__link--sublist menu__link--active" href="#!">Guides (Android)</a><ul class="menu__list"><li class="menu__list-item"><a aria-current="page" class="menu__link menu__link--active active" tabindex="0" href="/docs/0.60/native-modules-android">Native Modules</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/0.60/native-components-android">Native UI Components</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/0.60/headless-js-android">Headless JS</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/0.60/signed-apk-android">Publishing to Google Play Store</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/0.60/removing-default-permissions">Removing Default Permissions</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/0.60/hermes">Using Hermes</a></li></ul></li></ul></div></div></div><main class="docMainContainer_1zi2"><div class="container padding-vert--lg docItemWrapper_1hMI"><div class="row"><div class="col docItemCol_2AGf"><div class="alert alert--warning margin-bottom--md" role="alert"><div>This is documentation for React Native <strong>0.60</strong>, which is no longer actively maintained.</div><div class="margin-top--md">For up-to-date documentation, see the <strong><a href="/docs/native-modules-android">latest version</a></strong> (0.64).</div></div><div class="docItemContainer_1tAC"><article><div><span class="badge badge--secondary">Version: 0.60</span></div><header><h1 class="docTitle_cWlf">Native Modules</h1></header><div class="markdown"><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 aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="native-module-setup"></a>Native Module Setup<a class="hash-link" href="#native-module-setup" title="Direct link to heading">#</a></h2><p>Native modules are usually distributed as npm packages, apart from the typical javascript files and resources they will contain an Android library project. This project is, from NPM&#x27;s perspective similar to any other media asset, meaning there isn&#x27;t anything unique about it from this point of view. To get the basic scaffolding make sure to read <a href="/docs/0.60/native-modules-setup">Native Modules Setup</a> guide first.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="enable-gradle"></a>Enable Gradle<a class="hash-link" href="#enable-gradle" title="Direct link to heading">#</a></h3><p>If you plan to make changes in Java code, we recommend enabling <a href="https://docs.gradle.org/2.9/userguide/gradle_daemon.html" target="_blank" rel="noopener noreferrer">Gradle Daemon</a> to speed up builds.</p><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="the-toast-module"></a>The Toast Module<a class="hash-link" href="#the-toast-module" title="Direct link to heading">#</a></h2><p>This guide will use the <a href="http://developer.android.com/reference/android/widget/Toast.html" target="_blank" rel="noopener noreferrer">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>ToastExample.show(&#x27;Awesome&#x27;, ToastExample.SHORT);</code> from JavaScript to display a short toast on the screen.</p><p>Create a new Java Class named <code>ToastModule.java</code> inside <code>android/app/src/main/java/com/your-app-name/</code> folder with the content below:</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">// ToastModule.java</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">package com.your-app-name;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import android.widget.Toast;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.NativeModule;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.ReactApplicationContext;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.ReactContext;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.ReactContextBaseJavaModule;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.ReactMethod;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import java.util.Map;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import java.util.HashMap;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">public class ToastModule extends ReactContextBaseJavaModule {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private static ReactApplicationContext reactContext;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private static final String DURATION_SHORT_KEY = &quot;SHORT&quot;;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private static final String DURATION_LONG_KEY = &quot;LONG&quot;;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> ToastModule(ReactApplicationContext context) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> super(context);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> reactContext = context;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></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>ToastExample</code> so that we can access it through <code>React.NativeModules.ToastExample</code> in JavaScript.</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public String getName() {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> return &quot;ToastExample&quot;;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></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="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public Map&lt;String, Object&gt; getConstants() {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> final Map&lt;String, Object&gt; constants = new HashMap&lt;&gt;();</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> return constants;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></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="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @ReactMethod</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public void show(String message, int duration) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> Toast.makeText(getReactApplicationContext(), message, duration).show();</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="argument-types"></a>Argument Types<a class="hash-link" href="#argument-types" title="Direct link to heading">#</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="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-jsx codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">Boolean </span><span class="token operator" style="color:#fc929e">-</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> Bool</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">Integer </span><span class="token operator" style="color:#fc929e">-</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> Number</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">Double </span><span class="token operator" style="color:#fc929e">-</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> Number</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">Float </span><span class="token operator" style="color:#fc929e">-</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> Number</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">String </span><span class="token operator" style="color:#fc929e">-</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> String</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">Callback </span><span class="token operator" style="color:#fc929e">-</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">ReadableMap </span><span class="token operator" style="color:#fc929e">-</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> Object</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">ReadableArray </span><span class="token operator" style="color:#fc929e">-</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> Array</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></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" rel="noopener noreferrer">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" rel="noopener noreferrer">ReadableArray</a></p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="register-the-module"></a>Register the Module<a class="hash-link" href="#register-the-module" title="Direct link to heading">#</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><p>create a new Java Class named <code>CustomToastPackage.java</code> inside <code>android/app/src/main/java/com/your-app-name/</code> folder with the content below:</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">// CustomToastPackage.java</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">package com.your-app-name;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.ReactPackage;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.NativeModule;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.ReactApplicationContext;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.uimanager.ViewManager;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import java.util.ArrayList;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import java.util.Collections;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import java.util.List;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">public class CustomToastPackage implements ReactPackage {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public List&lt;ViewManager&gt; createViewManagers(ReactApplicationContext reactContext) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> return Collections.emptyList();</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public List&lt;NativeModule&gt; createNativeModules(</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> ReactApplicationContext reactContext) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> List&lt;NativeModule&gt; modules = new ArrayList&lt;&gt;();</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> modules.add(new ToastModule(reactContext));</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> return modules;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><p>The package needs to be provided in the <code>getPackages</code> method of the <code>MainApplication.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/MainApplication.java</code>.</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">// MainApplication.java</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.your-app-name.CustomToastPackage; // &lt;-- Add this line with your package name.</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">protected List&lt;ReactPackage&gt; getPackages() {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @SuppressWarnings(&quot;UnnecessaryLocalVariable&quot;)</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> List&lt;ReactPackage&gt; packages = new PackageList(this).getPackages();</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> // Packages that cannot be autolinked yet can be added manually here, for example:</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> // packages.add(new MyReactNativePackage());</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> packages.add(new CustomToastPackage()); // &lt;-- Add this line with your package name.</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> return packages;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><p>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><p>Create a new JavaScript file named <code>ToastExample.js</code> with the content below:</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-jsx codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token comment" style="color:#93a1a1">/**</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token comment" style="color:#93a1a1"> * This exposes the native ToastExample module as a JS module. This has a</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token comment" style="color:#93a1a1"> * function &#x27;show&#x27; which takes the following parameters:</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token comment" style="color:#93a1a1"> *</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token comment" style="color:#93a1a1"> * 1. String message: A string with the text to toast</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token comment" style="color:#93a1a1"> * 2. int duration: The duration of the toast. May be ToastExample.SHORT or</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token comment" style="color:#93a1a1"> * ToastExample.LONG</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token comment" style="color:#93a1a1"> */</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> NativeModules </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">&#x27;react-native&#x27;</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">exports </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> NativeModules</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">ToastExample</span><span class="token punctuation" style="color:#657b83">;</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><p>Now, from your other JavaScript file you can call the method like this:</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-jsx codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> ToastExample </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">&#x27;./ToastExample&#x27;</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">ToastExample</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">show</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">&#x27;Awesome&#x27;</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> ToastExample</span><span class="token punctuation" style="color:#657b83">.</span><span class="token constant" style="color:#5a9bcf">SHORT</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><p>Please make sure this JavaScript is in the same hierarchy as <code>ToastExample.js</code>.</p><h2><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="beyond-toasts"></a>Beyond Toasts<a class="hash-link" href="#beyond-toasts" title="Direct link to heading">#</a></h2><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="callbacks"></a>Callbacks<a class="hash-link" href="#callbacks" title="Direct link to heading">#</a></h3><p>Native modules also support a unique kind of argument - a callback. In most cases it is used to provide the function call result to JavaScript.</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.Callback;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">public class UIManagerModule extends ReactContextBaseJavaModule {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @ReactMethod</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public void measureLayout(</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> int tag,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> int ancestorTag,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> Callback errorCallback,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> Callback successCallback) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> try {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> measureLayout(tag, ancestorTag, mMeasureBuffer);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> float relativeX = PixelUtil.toDIPFromPixel(mMeasureBuffer[0]);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> float relativeY = PixelUtil.toDIPFromPixel(mMeasureBuffer[1]);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> float width = PixelUtil.toDIPFromPixel(mMeasureBuffer[2]);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> float height = PixelUtil.toDIPFromPixel(mMeasureBuffer[3]);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> successCallback.invoke(relativeX, relativeY, width, height);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> } catch (IllegalViewOperationException e) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> errorCallback.invoke(e.getMessage());</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><p>This method would be accessed in JavaScript using:</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-jsx codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">UIManager</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">measureLayout</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">msg</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">msg</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">x</span><span class="token parameter punctuation" style="color:#657b83">,</span><span class="token parameter"> y</span><span class="token parameter punctuation" style="color:#657b83">,</span><span class="token parameter"> width</span><span class="token parameter punctuation" style="color:#657b83">,</span><span class="token parameter"> height</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">x </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">&#x27;:&#x27;</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> y </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">&#x27;:&#x27;</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> width </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">&#x27;:&#x27;</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> height</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></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 aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="promises"></a>Promises<a class="hash-link" href="#promises" title="Direct link to heading">#</a></h3><p>Native modules can also fulfill a promise, which can simplify your JavaScript, 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="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.Promise;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">public class UIManagerModule extends ReactContextBaseJavaModule {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private static final String E_LAYOUT_ERROR = &quot;E_LAYOUT_ERROR&quot;;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @ReactMethod</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public void measureLayout(</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> int tag,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> int ancestorTag,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> Promise promise) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> try {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> measureLayout(tag, ancestorTag, mMeasureBuffer);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> WritableMap map = Arguments.createMap();</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> map.putDouble(&quot;relativeX&quot;, PixelUtil.toDIPFromPixel(mMeasureBuffer[0]));</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> map.putDouble(&quot;relativeY&quot;, PixelUtil.toDIPFromPixel(mMeasureBuffer[1]));</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> map.putDouble(&quot;width&quot;, PixelUtil.toDIPFromPixel(mMeasureBuffer[2]));</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> map.putDouble(&quot;height&quot;, PixelUtil.toDIPFromPixel(mMeasureBuffer[3]));</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> promise.resolve(map);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> } catch (IllegalViewOperationException e) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> promise.reject(E_LAYOUT_ERROR, e);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></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="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-jsx codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token keyword" style="color:#c5a5c5">async</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">measureLayout</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">var</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> relativeX</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> relativeY</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> width</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> height</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">await</span><span class="token plain"> UIManager</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">measureLayout</span><span class="token punctuation" style="color:#657b83">(</span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> relativeX </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">&#x27;:&#x27;</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> relativeY </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">&#x27;:&#x27;</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> width </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">&#x27;:&#x27;</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> height</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">error</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"></span><span class="token function" style="color:#79b6f2">measureLayout</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="threading"></a>Threading<a class="hash-link" href="#threading" title="Direct link to heading">#</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 aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="sending-events-to-javascript"></a>Sending Events to JavaScript<a class="hash-link" href="#sending-events-to-javascript" title="Direct link to heading">#</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="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.modules.core.DeviceEventManagerModule;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.WritableMap;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">import com.facebook.react.bridge.Arguments;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">private void sendEvent(ReactContext reactContext,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> String eventName,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @Nullable WritableMap params) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> reactContext</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> .emit(eventName, params);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">WritableMap params = Arguments.createMap();</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">params.putString(&quot;eventProperty&quot;, &quot;someValue&quot;);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">sendEvent(reactContext, &quot;EventReminder&quot;, params);</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><p>JavaScript modules can then register to receive events by <code>addListener</code> on the NativeEventEmitter class.</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-jsx codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> NativeEventEmitter</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> NativeModules </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">&#x27;react-native&#x27;</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"></span><span class="token operator" style="color:#fc929e">...</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token function" style="color:#79b6f2">componentDidMount</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token operator" style="color:#fc929e">...</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> eventEmitter </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">NativeEventEmitter</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">NativeModules</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">ToastExample</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> eventEmitter</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">addListener</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">&#x27;EventReminder&#x27;</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">eventProperty</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// &quot;someValue&quot;</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token operator" style="color:#fc929e">...</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="getting-activity-result-from-startactivityforresult"></a>Getting activity result from <code>startActivityForResult</code><a class="hash-link" href="#getting-activity-result-from-startactivityforresult" title="Direct link to heading">#</a></h3><p>You&#x27;ll need to listen to <code>onActivityResult</code> if you want to get results from an activity you started with <code>startActivityForResult</code>. To do this, you must extend <code>BaseActivityEventListener</code> or implement <code>ActivityEventListener</code>. The former is preferred as it is more resilient to API changes. Then, you need to register the listener in the module&#x27;s constructor,</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">reactContext.addActivityEventListener(mActivityResultListener);</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><p>Now you can listen to <code>onActivityResult</code> by implementing the following method:</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">@Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">public void onActivityResult(</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> final Activity activity,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> final int requestCode,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> final int resultCode,</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> final Intent intent) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> // Your logic here</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><p>We will implement a basic image picker to demonstrate this. The image picker will expose the method <code>pickImage</code> to JavaScript, which will return the path of the image when called.</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">public class ImagePickerModule extends ReactContextBaseJavaModule {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private static final int IMAGE_PICKER_REQUEST = 467081;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private static final String E_ACTIVITY_DOES_NOT_EXIST = &quot;E_ACTIVITY_DOES_NOT_EXIST&quot;;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private static final String E_PICKER_CANCELLED = &quot;E_PICKER_CANCELLED&quot;;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private static final String E_FAILED_TO_SHOW_PICKER = &quot;E_FAILED_TO_SHOW_PICKER&quot;;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private static final String E_NO_IMAGE_DATA_FOUND = &quot;E_NO_IMAGE_DATA_FOUND&quot;;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private Promise mPickerPromise;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> if (requestCode == IMAGE_PICKER_REQUEST) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> if (mPickerPromise != null) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> if (resultCode == Activity.RESULT_CANCELED) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> mPickerPromise.reject(E_PICKER_CANCELLED, &quot;Image picker was cancelled&quot;);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> } else if (resultCode == Activity.RESULT_OK) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> Uri uri = intent.getData();</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> if (uri == null) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> mPickerPromise.reject(E_NO_IMAGE_DATA_FOUND, &quot;No image data found&quot;);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> } else {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> mPickerPromise.resolve(uri.toString());</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> mPickerPromise = null;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> };</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> ImagePickerModule(ReactApplicationContext reactContext) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> super(reactContext);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> // Add the listener for `onActivityResult`</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> reactContext.addActivityEventListener(mActivityEventListener);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public String getName() {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> return &quot;ImagePickerModule&quot;;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> @ReactMethod</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> public void pickImage(final Promise promise) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> Activity currentActivity = getCurrentActivity();</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> if (currentActivity == null) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> promise.reject(E_ACTIVITY_DOES_NOT_EXIST, &quot;Activity doesn&#x27;t exist&quot;);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> return;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> // Store the promise to resolve/reject when picker returns data</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> mPickerPromise = promise;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> try {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> final Intent galleryIntent = new Intent(Intent.ACTION_PICK);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> galleryIntent.setType(&quot;image/*&quot;);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> final Intent chooserIntent = Intent.createChooser(galleryIntent, &quot;Pick an image&quot;);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> currentActivity.startActivityForResult(chooserIntent, IMAGE_PICKER_REQUEST);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> } catch (Exception e) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> mPickerPromise.reject(E_FAILED_TO_SHOW_PICKER, e);</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> mPickerPromise = null;</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_E4oP" id="listening-to-lifecycle-events"></a>Listening to LifeCycle events<a class="hash-link" href="#listening-to-lifecycle-events" title="Direct link to heading">#</a></h3><p>Listening to the activity&#x27;s LifeCycle events such as <code>onResume</code>, <code>onPause</code> etc. is very similar to how we implemented <code>ActivityEventListener</code>. The module must implement <code>LifecycleEventListener</code>. Then, you need to register a listener in the module&#x27;s constructor,</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">reactContext.addLifecycleEventListener(this);</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div><p>Now you can listen to the activity&#x27;s LifeCycle events by implementing the following methods:</p><div class="mdxCodeBlock_1daz"><div class="codeBlockContent_2es_"><div tabindex="0" class="prism-code language-java codeBlock_27aQ thin-scrollbar"><div class="codeBlockLines_2rCb" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">@Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">public void onHostResume() {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> // Activity `onResume`</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">@Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">public void onHostPause() {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> // Activity `onPause`</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain" style="display:inline-block">
</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">@Override</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">public void onHostDestroy() {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> // Activity `onDestroy`</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div></div></div><button type="button" aria-label="Copy code to clipboard" class="copyButton_2bml">Copy</button></div></div></div></article><div class="docMetadata margin-vert--xl"><div class="row"><div class="col"><a href="https://github.com/facebook/react-native-website/blob/master/website/versioned_docs/version-0.60/native-modules-android.md" target="_blank" rel="noreferrer noopener"><svg fill="currentColor" height="1.2em" width="1.2em" preserveAspectRatio="xMidYMid meet" role="img" viewBox="0 0 40 40" class="iconEdit_2Hwv"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col text--right"><em><small class="docMetadata-updated">Last updated on <time datetime="2020-10-29T04:19:29.000Z" class="docLastUpdatedAt_1gIo">10/29/2020</time></small></em></div></div></div><div class="margin-vert--lg"><nav class="pagination-nav" aria-label="Blog list page navigation"><div class="pagination-nav__item"><a class="pagination-nav__link" href="/docs/0.60/app-extensions"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">« App Extensions</div></a></div><div class="pagination-nav__item pagination-nav__item--next"><a class="pagination-nav__link" href="/docs/0.60/native-components-android"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Native UI Components »</div></a></div></nav></div></div></div><div class="col col--3"><div class="tableOfContents_1zTD thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#native-module-setup" class="table-of-contents__link">Native Module Setup</a><ul><li><a href="#enable-gradle" class="table-of-contents__link">Enable Gradle</a></li></ul></li><li><a href="#the-toast-module" class="table-of-contents__link">The Toast Module</a><ul><li><a href="#argument-types" class="table-of-contents__link">Argument Types</a></li><li><a href="#register-the-module" class="table-of-contents__link">Register the Module</a></li></ul></li><li><a href="#beyond-toasts" class="table-of-contents__link">Beyond Toasts</a><ul><li><a href="#callbacks" class="table-of-contents__link">Callbacks</a></li><li><a href="#promises" class="table-of-contents__link">Promises</a></li><li><a href="#threading" class="table-of-contents__link">Threading</a></li><li><a href="#sending-events-to-javascript" class="table-of-contents__link">Sending Events to JavaScript</a></li><li><a href="#getting-activity-result-from-startactivityforresult" class="table-of-contents__link">Getting activity result from <code>startActivityForResult</code></a></li><li><a href="#listening-to-lifecycle-events" class="table-of-contents__link">Listening to LifeCycle events</a></li></ul></li></ul></div></div></div></div></main></div></div><footer class="footer footer--dark"><div class="container"><div class="row footer__links"><div class="col footer__col"><h4 class="footer__title">Docs</h4><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/docs/getting-started">Getting Started</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/tutorial">Tutorial</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/components-and-apis">Components and APIs</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/more-resources">More Resources</a></li></ul></div><div class="col footer__col"><h4 class="footer__title">Community</h4><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/help">The React Native Community</a></li><li class="footer__item"><a class="footer__link-item" href="/showcase">Who&#x27;s using React Native?</a></li><li class="footer__item"><a href="https://stackoverflow.com/questions/tagged/react-native" target="_blank" rel="noopener noreferrer" class="footer__link-item">Ask Questions on Stack Overflow</a></li><li class="footer__item"><a href="https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer" class="footer__link-item">Contributor Guide</a></li><li class="footer__item"><a href="https://dev.to/t/reactnative" target="_blank" rel="noopener noreferrer" class="footer__link-item">DEV Community</a></li></ul></div><div class="col footer__col"><h4 class="footer__title">Find us</h4><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/blog">Blog</a></li><li class="footer__item"><a href="https://twitter.com/reactnative" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter</a></li><li class="footer__item"><a href="https://github.com/facebook/react-native" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub</a></li></ul></div><div class="col footer__col"><h4 class="footer__title">More</h4><ul class="footer__items"><li class="footer__item"><a href="https://reactjs.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">React</a></li><li class="footer__item"><a href="https://opensource.facebook.com/legal/privacy" target="_blank" rel="noopener noreferrer" class="footer__link-item">Privacy Policy</a></li><li class="footer__item"><a href="https://opensource.facebook.com/legal/terms" target="_blank" rel="noopener noreferrer" class="footer__link-item">Terms of Service</a></li></ul></div></div><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a href="https://opensource.facebook.com" target="_blank" rel="noopener noreferrer" class="footerLogoLink_3cAK"><img class="footer__logo" alt="Facebook Open Source Logo" src="/img/oss_logo.png"></a></div><div class="footer__copyright">Copyright © 2021 Facebook, Inc.</div></div></div></footer></div>
<script src="/styles.9d29dd5a.js"></script>
<script src="/runtime~main.b00a5634.js"></script>
<script src="/main.4103a08e.js"></script>
<script src="/1.7a6193e2.js"></script>
<script src="/2.9b40dc51.js"></script>
<script src="/1089.caa7a648.js"></script>
<script src="/ae345423.7c9998ff.js"></script>
<script src="/17896441.b54b3e3c.js"></script>
<script src="/3720ec3a.03c72c47.js"></script>
</body>
</html>