forked from facebook/react-native
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
186 lines (177 loc) · 39.6 KB
/
index.html
File metadata and controls
186 lines (177 loc) · 39.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Publishing to Google Play Store · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="Android requires that all apps be digitally signed with a certificate before they can be installed. In order to distribute your Android application via [Google Play store](https://play.google.com/store) it needs to be signed with a release key that then needs to be used for all future updates. Since 2017 it is possible for Google Play to manage signing releases automatically thanks to [App Signing by Google Play](https://developer.android.com/studio/publish/app-signing#app-signing-google-play) functionality. However, before your application binary is uploaded to Google Play it needs to be signed with an upload key. The [Signing Your Applications](https://developer.android.com/tools/publishing/app-signing.html) page on Android Developers documentation describes the topic in detail. This guide covers the process in brief, as well as lists the steps required to package the JavaScript bundle."/><meta name="docsearch:version" content="0.34"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Publishing to Google Play Store · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://reactnative.dev/"/><meta property="og:description" content="Android requires that all apps be digitally signed with a certificate before they can be installed. In order to distribute your Android application via [Google Play store](https://play.google.com/store) it needs to be signed with a release key that then needs to be used for all future updates. Since 2017 it is possible for Google Play to manage signing releases automatically thanks to [App Signing by Google Play](https://developer.android.com/studio/publish/app-signing#app-signing-google-play) functionality. However, before your application binary is uploaded to Google Play it needs to be signed with an upload key. The [Signing Your Applications](https://developer.android.com/tools/publishing/app-signing.html) page on Android Developers documentation describes the topic in detail. This guide covers the process in brief, as well as lists the steps required to package the JavaScript bundle."/><meta property="og:image" content="https://reactnative.dev/img/logo-og.png"/><meta name="twitter:card" content="summary"/><meta name="twitter:image" content="https://reactnative.dev/img/logo-og.png"/><link rel="shortcut icon" href="/img/favicon.ico"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://reactnative.dev/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://reactnative.dev/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-41298772-2', 'auto');
ga('send', 'pageview');
</script><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/focus-visible@5.0.2/dist/focus-visible.min.js"></script><script type="text/javascript" src="https://snack.expo.io/embed.js"></script><script type="text/javascript" src="https://platform.twitter.com/widgets.js"></script><script type="text/javascript" src="https://buttons.github.io/buttons.js"></script><script type="text/javascript" src="/js/codeblocks.js"></script><script type="text/javascript" src="/js/tabs.js"></script><script type="text/javascript" src="/js/docs-rating.js"></script><script type="text/javascript" src="/js/announcement.js"></script><script src="https://unpkg.com/vanilla-back-to-top@7.1.14/dist/vanilla-back-to-top.min.js"></script><script>
document.addEventListener('DOMContentLoaded', function() {
addBackToTop(
{"zIndex":100}
)
});
</script><script src="/js/scrollSpy.js"></script><link rel="stylesheet" href="/css/prism.css"/><link rel="stylesheet" href="/css/main.css"/><script src="/js/codetabs.js"></script></head><body class="sideNavVisible separateOnPageNav"><div class="fixedHeaderContainer"><div class="headerWrapper wrapper"><header><a href="/"><img class="logo" src="/img/header_logo.svg" alt="React Native"/><h2 class="headerTitleWithLogo">React Native</h2></a><a href="/versions"><h3>0.34</h3></a><div class="navigationWrapper navigationSlider"><nav class="slidingNav"><ul class="nav-site nav-site-internal"><li class="siteNavGroupActive"><a href="/docs/0.34/getting-started" target="_self">Docs</a></li><li class="siteNavGroupActive"><a href="/docs/0.34/components-and-apis" target="_self">Components</a></li><li class=""><a href="/docs/0.34/accessibilityinfo" target="_self">API</a></li><li class=""><a href="/help" target="_self">Community</a></li><li class=""><a href="/blog/" target="_self">Blog</a></li><li class="navSearchWrapper reactNavSearchWrapper"><input type="text" id="search_input_react" placeholder="Search" title="Search"/></li><li class=""><a href="https://github.com/facebook/react-native" target="_self">GitHub</a></li></ul></nav></div></header></div></div><div class="navPusher"><div class="docMainWrapper wrapper"><div class="docsNavContainer" id="docsNav"><nav class="toc"><div class="toggleNav"><section class="navWrapper wrapper"><div class="navBreadcrumb wrapper"><div class="navToggle" id="navToggler"><div class="hamburger-menu"><div class="line1"></div><div class="line2"></div><div class="line3"></div></div></div><h2><i>›</i><span>Guides (Android)</span></h2><div class="tocToggler" id="tocToggler"><i class="icon-toc"></i></div></div><div class="navGroups"><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">The Basics<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/0.34/getting-started">Getting Started</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/tutorial">Learn the Basics</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/props">Props</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/state">State</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/style">Style</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/height-and-width">Height and Width</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/flexbox">Layout with Flexbox</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/handling-text-input">Handling Text Input</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/handling-touches">Handling Touches</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/using-a-scrollview">Using a ScrollView</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/using-a-listview">Using List Views</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/network">Networking</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/more-resources">More Resources</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">Guides<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/0.34/components-and-apis">Components and APIs</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/platform-specific-code">Platform Specific Code</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/navigation">Navigating Between Screens</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/images">Images</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/animations">Animations</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/accessibility">Accessibility</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/improvingux">Improving User Experience</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/timers">Timers</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/debugging">Debugging</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/performance">Performance</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/gesture-responder-system">Gesture Responder System</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/javascript-environment">JavaScript Environment</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/direct-manipulation">Direct Manipulation</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/colors">Color Reference</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/integration-with-existing-apps">Integration with Existing Apps</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/running-on-device">Running On Device</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/upgrading">Upgrading to new React Native versions</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/troubleshooting">Troubleshooting</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/native-modules-setup">Native Modules Setup</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">Guides (iOS)<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/0.34/native-modules-ios">Native Modules</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/native-components-ios">Native UI Components</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/linking-libraries-ios">Linking Libraries</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/running-on-simulator-ios">Running On Simulator</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/communication-ios">Communication between native and React Native</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/building-for-tv">Building For TV Devices</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/app-extensions">App Extensions</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">Guides (Android)<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/0.34/native-modules-android">Native Modules</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/native-components-android">Native UI Components</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/headless-js-android">Headless JS</a></li><li class="navListItem navListItemActive"><a class="navItem" href="/docs/0.34/signed-apk-android">Publishing to Google Play Store</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/removing-default-permissions">Removing Default Permissions</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">Components<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/0.34/activityindicator">ActivityIndicator</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/datepickerios">DatePickerIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/drawerlayoutandroid">DrawerLayoutAndroid</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/image">Image</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/keyboardavoidingview">KeyboardAvoidingView</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/modal">Modal</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/navigator">Navigator</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/navigatorios">NavigatorIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/picker">Picker</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/pickerios">PickerIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/progressbarandroid">ProgressBarAndroid</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/progressviewios">ProgressViewIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/refreshcontrol">RefreshControl</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/scrollview">ScrollView</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/segmentedcontrolios">SegmentedControlIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/slider">Slider</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/snapshotviewios">SnapshotViewIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/statusbar">StatusBar</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/switch">Switch</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/tabbarios">TabBarIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/tabbarios-item">TabBarIOS.Item</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/text">Text</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/textinput">TextInput</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/toolbarandroid">ToolbarAndroid</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/touchablehighlight">TouchableHighlight</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/touchablenativefeedback">TouchableNativeFeedback</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/touchableopacity">TouchableOpacity</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/touchablewithoutfeedback">TouchableWithoutFeedback</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/viewpagerandroid">ViewPagerAndroid</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/webview">WebView</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">APIs<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/0.34/actionsheetios">ActionSheetIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/animated">Animated</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/appstate">AppState</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/asyncstorage">AsyncStorage</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/cameraroll">CameraRoll</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/clipboard">Clipboard</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/datepickerandroid">DatePickerAndroid</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/dimensions">Dimensions</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/easing">Easing</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/geolocation">Geolocation</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/imageeditor">ImageEditor</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/imagepickerios">ImagePickerIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/imagestore">ImageStore</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/image-style-props">Image Style Props</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/interactionmanager">InteractionManager</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/layout-props">Layout Props</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/layoutanimation">LayoutAnimation</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/linking">Linking</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/netinfo">NetInfo</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/panresponder">PanResponder</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/permissionsandroid">PermissionsAndroid</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/pixelratio">PixelRatio</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/pushnotificationios">PushNotificationIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/settings">Settings</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/shadow-props">Shadow Props</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/share">Share</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/statusbarios">StatusBarIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/stylesheet">StyleSheet</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/text-style-props">Text Style Props</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/timepickerandroid">TimePickerAndroid</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/toastandroid">ToastAndroid</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/transforms">Transforms</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/vibration">Vibration</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/vibrationios">VibrationIOS</a></li><li class="navListItem"><a class="navItem" href="/docs/0.34/view-style-props">View Style Props</a></li></ul></div></div></section></div><script>
var coll = document.getElementsByClassName('collapsible');
var checkActiveCategory = true;
for (var i = 0; i < coll.length; i++) {
var links = coll[i].nextElementSibling.getElementsByTagName('*');
if (checkActiveCategory){
for (var j = 0; j < links.length; j++) {
if (links[j].classList.contains('navListItemActive')){
coll[i].nextElementSibling.classList.toggle('hide');
coll[i].childNodes[1].classList.toggle('rotate');
checkActiveCategory = false;
break;
}
}
}
coll[i].addEventListener('click', function() {
var arrow = this.childNodes[1];
arrow.classList.toggle('rotate');
var content = this.nextElementSibling;
content.classList.toggle('hide');
});
}
document.addEventListener('DOMContentLoaded', function() {
createToggler('#navToggler', '#docsNav', 'docsSliderActive');
createToggler('#tocToggler', 'body', 'tocActive');
var headings = document.querySelector('.toc-headings');
headings && headings.addEventListener('click', function(event) {
var el = event.target;
while(el !== headings){
if (el.tagName === 'A') {
document.body.classList.remove('tocActive');
break;
} else{
el = el.parentNode;
}
}
}, false);
function createToggler(togglerSelector, targetSelector, className) {
var toggler = document.querySelector(togglerSelector);
var target = document.querySelector(targetSelector);
if (!toggler) {
return;
}
toggler.onclick = function(event) {
event.preventDefault();
target.classList.toggle(className);
};
}
});
</script></nav></div><div class="container mainContainer docsContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/signed-apk-android.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 id="__docusaurus" class="postHeaderTitle">Publishing to Google Play Store</h1></header><article><div><span><p>Android requires that all apps be digitally signed with a certificate before they can be installed. In order to distribute your Android application via <a href="https://play.google.com/store">Google Play store</a> it needs to be signed with a release key that then needs to be used for all future updates. Since 2017 it is possible for Google Play to manage signing releases automatically thanks to <a href="https://developer.android.com/studio/publish/app-signing#app-signing-google-play">App Signing by Google Play</a> functionality. However, before your application binary is uploaded to Google Play it needs to be signed with an upload key. The <a href="https://developer.android.com/tools/publishing/app-signing.html">Signing Your Applications</a> page on Android Developers documentation describes the topic in detail. This guide covers the process in brief, as well as lists the steps required to package the JavaScript bundle.</p>
<h3><a class="anchor" aria-hidden="true" id="generating-an-upload-key"></a><a href="#generating-an-upload-key" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Generating an upload key</h3>
<p>You can generate a private signing key using <code>keytool</code>. On Windows <code>keytool</code> must be run from <code>C:\Program Files\Java\jdkx.x.x_x\bin</code>.</p>
<pre><code class="hljs">$ keytool -genkeypair -v -keystore my-upload-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
</code></pre>
<p>This command prompts you for passwords for the keystore and key and for the Distinguished Name fields for your key. It then generates the keystore as a file called <code>my-upload-key.keystore</code>.</p>
<p>The keystore contains a single key, valid for 10000 days. The alias is a name that you will use later when signing your app, so remember to take note of the alias.</p>
<p>On Mac, if you're not sure where your JDK bin folder is, then perform the following command to find it:</p>
<pre><code class="hljs">$ /usr/libexec/java_home
</code></pre>
<p>It will output the directory of the JDK, which will look something like this:</p>
<pre><code class="hljs">/Library/Java/JavaVirtualMachines/jdkX.X.X_XXX.jdk/Contents/Home
</code></pre>
<p>Navigate to that directory by using the command <code>$ cd /your/jdk/path</code> and use the keytool command with sudo permission as shown below.</p>
<pre><code class="hljs">$ sudo keytool -genkey -v -keystore my-upload-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
</code></pre>
<p><em>Note: Remember to keep the keystore file private. In case you've lost upload key or it's been compromised you should <a href="https://support.google.com/googleplay/android-developer/answer/7384423#reset">follow these instructions</a>.</em></p>
<h3><a class="anchor" aria-hidden="true" id="setting-up-gradle-variables"></a><a href="#setting-up-gradle-variables" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Setting up Gradle variables</h3>
<ol>
<li>Place the <code>my-upload-key.keystore</code> file under the <code>android/app</code> directory in your project folder.</li>
<li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code>, and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li>
</ol>
<pre><code class="hljs"><span class="hljs-attr">MYAPP_UPLOAD_STORE_FILE</span>=my-upload-key.keystore
<span class="hljs-attr">MYAPP_UPLOAD_KEY_ALIAS</span>=my-key-alias
<span class="hljs-attr">MYAPP_UPLOAD_STORE_PASSWORD</span>=*****
<span class="hljs-attr">MYAPP_UPLOAD_KEY_PASSWORD</span>=*****
</code></pre>
<p>These are going to be global Gradle variables, which we can later use in our Gradle config to sign our app.</p>
<p><em>Note about security: If you are not keen on storing your passwords in plaintext, and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p>
<h3><a class="anchor" aria-hidden="true" id="adding-signing-config-to-your-apps-gradle-config"></a><a href="#adding-signing-config-to-your-apps-gradle-config" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Adding signing config to your app's Gradle config</h3>
<p>The last configuration step that needs to be done is to setup release builds to be signed using upload key. Edit the file <code>android/app/build.gradle</code> in your project folder, and add the signing config,</p>
<pre><code class="hljs css language-gradle">...
android {
...
defaultConfig { ... }
signingConfigs {
release {
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">project</span>.hasProperty(<span class="hljs-string">'MYAPP_UPLOAD_STORE_FILE'</span>)) {
storeFile <span class="hljs-keyword">file</span>(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
}
buildTypes {
release {
...
signingConfig signingConfigs.release
}
}
}
...
</code></pre>
<h3><a class="anchor" aria-hidden="true" id="generating-the-release-apk"></a><a href="#generating-the-release-apk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Generating the release APK</h3>
<p>Run the following in a terminal:</p>
<pre><code class="hljs css language-sh">$ <span class="token builtin class-name">cd</span> android
$ ./gradlew bundleRelease
</code></pre>
<p>Gradle's <code>bundleRelease</code> will bundle all the JavaScript needed to run your app into the AAB (<a href="https://developer.android.com/guide/app-bundle">Android App Bundle</a>). If you need to change the way the JavaScript bundle and/or drawable resources are bundled (e.g. if you changed the default file/folder names or the general structure of the project), have a look at <code>android/app/build.gradle</code> to see how you can update it to reflect these changes.</p>
<blockquote>
<p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make the release build skip bundling JS and assets into the app binary.</p>
</blockquote>
<p>The generated AAB can be found under <code>android/app/build/outputs/bundle/release/app.aab</code>, and is ready to be uploaded to Google Play.</p>
<p><em>Note: In order for Google Play to accept AAB format the App Signing by Google Play needs to be configured for your application on the Google Play Console. If you are updating an existing app that doesn't use App Signing by Google Play, please check our <a href="#migrating-old-android-react-native-apps-to-use-app-signing-by-google-play">migration section</a> to learn how to perform that configuration change.</em></p>
<h3><a class="anchor" aria-hidden="true" id="testing-the-release-build-of-your-app"></a><a href="#testing-the-release-build-of-your-app" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Testing the release build of your app</h3>
<p>Before uploading the release build to the Play Store, make sure you test it thoroughly. First uninstall any previous version of the app you already have installed. Install it on the device using:</p>
<pre><code class="hljs css language-sh">$ react-native run-android --variant<span class="token operator">=</span>release
</code></pre>
<p>Note that <code>--variant=release</code> is only available if you've set up signing as described above.</p>
<p>You can terminate any running bundler instances, since all your framework and JavaScript code is bundled in the APK's assets.</p>
<h3><a class="anchor" aria-hidden="true" id="publishing-to-other-stores"></a><a href="#publishing-to-other-stores" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Publishing to other stores</h3>
<p>By default, the generated APK has the native code for both x86 and ARMv7a CPU architectures. This makes it easier to share APKs that run on almost all Android devices. However, this has the downside that there will be some unused native code on any device, leading to unnecessarily bigger APKs.</p>
<p>You can create an APK for each CPU by changing the following line in android/app/build.gradle:</p>
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- ndk {</span>
<span class="hljs-deletion">- abiFilters "armeabi-v7a", "x86"</span>
<span class="hljs-deletion">- }</span>
<span class="hljs-deletion">- def enableSeparateBuildPerCPUArchitecture = false</span>
<span class="hljs-addition">+ def enableSeparateBuildPerCPUArchitecture = true</span>
</code></pre>
<p>Upload both these files to markets which support device targeting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/device-filtering-and-compatibility.html">Amazon AppStore</a>, and the users will automatically get the appropriate APK. If you want to upload to other markets, such as <a href="https://www.apkfiles.com/">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p>
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- universalApk false // If true, also generate a universal APK</span>
<span class="hljs-addition">+ universalApk true // If true, also generate a universal APK</span>
</code></pre>
<h3><a class="anchor" aria-hidden="true" id="enabling-proguard-to-reduce-the-size-of-the-apk-optional"></a><a href="#enabling-proguard-to-reduce-the-size-of-the-apk-optional" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Enabling Proguard to reduce the size of the APK (optional)</h3>
<p>Proguard is a tool that can slightly reduce the size of the APK. It does this by stripping parts of the React Native Java bytecode (and its dependencies) that your app is not using.</p>
<p><em><strong>IMPORTANT</strong>: Make sure to thoroughly test your app if you've enabled Proguard. Proguard often requires configuration specific to each native library you're using. See <code>app/proguard-rules.pro</code>.</em></p>
<p>To enable Proguard, edit <code>android/app/build.gradle</code>:</p>
<pre><code class="hljs css language-gradle"><span class="hljs-comment">/**
* Run Proguard to shrink the Java bytecode in release builds.
*/</span>
<span class="hljs-keyword">def</span> enableProguardInReleaseBuilds = <span class="hljs-keyword">true</span>
</code></pre>
<h3><a class="anchor" aria-hidden="true" id="migrating-old-android-react-native-apps-to-use-app-signing-by-google-play"></a><a href="#migrating-old-android-react-native-apps-to-use-app-signing-by-google-play" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Migrating old Android React Native apps to use App Signing by Google Play</h3>
<p>If you are migrating from previous version of React Native chances are your app does not use App Signing by Google Play feature. We recommend you enable that in order to take advantage from things like automatic app splitting. In order to migrate from the old way of signing you need to start by <a href="#generating-an-upload-key">generating new upload key</a> and then replacing release signing config in <code>android/app/build.gradle</code> to use the upload key instead of the release one (see section about <a href="#adding-signing-config-to-your-app-s-gradle-config">adding signing config to gradle</a>). Once that's done you should follow the <a href="https://support.google.com/googleplay/android-developer/answer/7384423">instructions from Google Play Help website</a> in order to send your original release key to Google Play.</p>
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/docs/0.34/headless-js-android"><span class="arrow-prev">← </span><span>Headless JS</span></a><a class="docs-next button" href="/docs/0.34/removing-default-permissions"><span>Removing Default Permissions</span><span class="arrow-next"> →</span></a></div></div></div><nav class="onPageNav"></nav></div><footer class="nav-footer" id="footer"><section class="sitemap"><div><h5>Docs</h5><a href="/docs/getting-started">Getting Started</a><a href="/docs/tutorial">Tutorial</a><a href="/docs/components-and-apis">Components and APIs</a><a href="/docs/more-resources">More Resources</a></div><div><h5>Community</h5><a href="/help">The React Native Community</a><a href="/showcase">Who's using React Native?</a><a href="https://stackoverflow.com/questions/tagged/react-native" target="_blank">Ask Questions on Stack Overflow</a><a href="https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md">Contributor Guide</a><a href="https://dev.to/t/reactnative" target="_blank">DEV Community</a></div><div><h5>More Resources</h5><a href="/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="https://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2020 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
document.addEventListener('keyup', function(e) {
if (e.target !== document.body) {
return;
}
// keyCode for '/' (slash)
if (e.keyCode === 191) {
const search = document.getElementById('search_input_react');
search && search.focus();
}
});
</script><script>
var search = docsearch({
apiKey: '2c98749b4a1e588efec53b2acec13025',
indexName: 'react-native-versions',
inputSelector: '#search_input_react',
algoliaOptions: {"facetFilters":["tags:0.34"],"hitsPerPage":5}
});
</script></body></html>