Skip to content

Platform Specifics: Android

Tommy Nguyen edited this page Apr 24, 2024 · 2 revisions

This page applies to:

Android iOS macOS visionOS Windows
>=0.0.7

Dependencies

  • Android Studio
    • Android SDK Platform 34
    • Required SDKs and build tools should be automatically installed by Android Studio. If this doesn't happen, you can manually install them by going into PreferencesAppearance & BehaviorSystem SettingsAndroid SDK.
  • [dev] Node LTS
  • [dev] Yarn

Building From Source

To build React Native from source, set react.buildFromSource=true in gradle.properties:

 #bridgelessEnabled=true

 # Uncomment the line below to build React Native from source.
-#react.buildFromSource=true
+react.buildFromSource=true

 # Version of Android NDK to build against.
 #ANDROID_NDK_VERSION=26.1.10909125

For more details on what this flag does, check out the documentation: How to Build from Source

If you're hitting build failures in C++ code, see fix(android): fix ndkVersion is unset when building from source.

Custom Application ID

You can set your own application identifier in the manifest.

 {
   "$schema": "https://raw.githubusercontent.com/microsoft/react-native-test-app/trunk/schema.json",
   "name": "Example",
   "displayName": "Example",
   "components": [...],
+  "android": {
+    "package": "com.contoso.Example"
+  },
   "resources": {...}
 }

Detox

As of Detox 17.x, follow the Android setup guide until you get to step 3. Open your android/build.gradle and add this section:

allprojects {
    repositories {
        maven {
            url("$rootDir/../../node_modules/detox/Detox-android")
        }
    }
    afterEvaluate { project ->
        def androidExtension = project.extensions.findByName('android')
        if (androidExtension != null && project.name == 'app') {
            androidExtension.defaultConfig {
                ndk {
                    abiFilters 'arm64-v8a', 'x86', 'x86_64'
                }
            }

            androidExtension.sourceSets.androidTest.java.srcDirs += <path to source set with DetoxTest class>

            project.dependencies {
                androidTestImplementation('com.wix:detox:+')
            }
        }
    }
}

Replace the path to the source set that includes the DetoxTest.java class you created in step 5. If your build.gradle is in example/android and the class is stored in example/android/app/src/androidTest/java/com/microsoft/reacttestapp/DetoxTest.java, you should use "$rootDir/app/src/androidTest/java".

You can skip steps 4, 6-8.

Kotlin

As of 1.6.5, you can specify the Kotlin version to build against in gradle.properties:

 #ANDROID_NDK_VERSION=26.1.10909125

 # Version of Kotlin to build against.
-#KOTLIN_VERSION=1.8.22
+KOTLIN_VERSION=1.8.22

New Architecture (previously Fabric, TurboModule, or Bridgeless)

You can enable New Architecture if you're on React Native 0.71 or greater. Bridgeless mode can be enabled starting from 0.73.

Add newArchEnabled=true to your gradle.properties:

 # to write custom TurboModules/Fabric components OR use libraries that
 # are providing them.
 # Note that this is incompatible with web debugging.
-#newArchEnabled=true
+newArchEnabled=true
 #bridgelessEnabled=true

 # Uncomment the line below if building react-native from source

Additionally, you can enable bridgeless mode with bridgelessEnabled=true.

Make sure that your build.gradle is up-to-date:

buildscript {
    def androidTestAppDir = "../node_modules/react-native-test-app/android"
    apply(from: "${androidTestAppDir}/dependencies.gradle")

    repositories {
        mavenCentral()
        google()
    }

    dependencies {
        getReactNativeDependencies().each { dependency ->
            classpath(dependency)
        }
    }
}

Warning

Note that New Architecture is still experimental. You can find more information in the documentation.

Signing Your App

There are a couple of ways to configure signing in the Android test app.

Via the Manifest (app.json)

The JSON schema follows the Gradle DSL very closely. Below is what one would add for the debug and release flavors:

{
  ...
  "android": {
    "signingConfigs": {
      "debug": {                        // optional
        "keyAlias": "androiddebugkey",  // optional, defaults to "androiddebugkey"
        "keyPassword": "android",       // optional, defaults to "android
        "storeFile": "debug.keystore",  // required
        "storePassword": "android"      // optional, defaults to "android
      },
      "release": {                      // optional
        "keyAlias": "androiddebugkey",  // optional, defaults to "androiddebugkey"
        "keyPassword": "android",       // optional, defaults to "android
        "storeFile": "debug.keystore",  // required
        "storePassword": "android"      // optional, defaults to "android
      }
    }
  }
}

Via Gradle

You can add signing configurations by retrieving the android extension, e.g.:

allprojects {
    afterEvaluate { project ->
        def androidExt = project.extensions.findByName("android")
        if (androidExt != null && project.name == "app") {
            androidExt.signingConfigs {
                test {
                    keyAlias "androiddebugkey"
                    keyPassword "android"
                    storeFile file("debug.keystore")
                    storePassword "android"
                }
            }

            androidExt.buildTypes.release.signingConfig = androidExt.signingConfigs.test
            androidExt.testBuildType = "release"
        }
    }
}

Using Fragments

On Android, you can add fragments to the home screen by using their fully qualified class names, e.g. com.example.app.MyFragment, as app key:

"components": [
  {
    "appKey": "com.example.app.MyFragment",
    "displayName": "App"
  }
]

If you need to get the ReactNativeHost instance within MyFragment, you can request it as a service from the context:

@Override
@SuppressLint("WrongConstant")
public void onAttach(@NonNull Context context) {
    super.onAttach(context);

    ReactNativeHost reactNativeHost = (ReactNativeHost)
        context.getSystemService("service:reactNativeHostService");
    ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager();
}

Flipper (deprecated as of 3.0)

As of 0.1.13, Flipper is enabled by default if you're on React Native 0.62 or greater. You don't have to make any changes locally. If you need to use a specific version or want to disable it, define FLIPPER_VERSION in your gradle.properties:

 # These properties are required to enable AndroidX for the test app.
 android.useAndroidX=true
 android.enableJetifier=true

+# To use Flipper 0.33.1:
+FLIPPER_VERSION=0.33.1

 # To disable Flipper, set it to `false` instead:
 #FLIPPER_VERSION=false