diff --git a/template/template/android/app/build.gradle b/template/template/android/app/build.gradle index 4e64e6a0..3081a1f2 100644 --- a/template/template/android/app/build.gradle +++ b/template/template/android/app/build.gradle @@ -114,16 +114,19 @@ def jscFlavor = 'org.webkit:android-jsc:+' /** * Whether to enable the Hermes VM. * - * This should be set on project.ext.react and mirrored here. If it is not set + * This should be set on project.ext.react and that value will be read here. If it is not set * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode * and the benefits of using Hermes will therefore be sharply reduced. */ def enableHermes = project.ext.react.get("enableHermes", false); /** - * Architectures to build native code for in debug. + * Architectures to build native code for. */ -def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures") +def reactNativeArchitectures() { + def value = project.getProperties().get("reactNativeArchitectures") + return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] +} android { ndkVersion rootProject.ext.ndkVersion @@ -136,13 +139,82 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" + buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() + + if (isNewArchitectureEnabled()) { + // We configure the NDK build only if you decide to opt-in for the New Architecture. + externalNativeBuild { + ndkBuild { + arguments "APP_PLATFORM=android-21", + "APP_STL=c++_shared", + "NDK_TOOLCHAIN_VERSION=clang", + "GENERATED_SRC_DIR=$buildDir/generated/source", + "PROJECT_BUILD_DIR=$buildDir", + "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", + "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build", + "NODE_MODULES_DIR=$rootDir/../node_modules" + cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1" + cppFlags "-std=c++17" + // Make sure this target name is the same you specify inside the + // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable. + targets "helloworld_appmodules" + } + } + if (!enableSeparateBuildPerCPUArchitecture) { + ndk { + abiFilters (*reactNativeArchitectures()) + } + } + } } + + if (isNewArchitectureEnabled()) { + // We configure the NDK build only if you decide to opt-in for the New Architecture. + externalNativeBuild { + ndkBuild { + path "$projectDir/src/main/jni/Android.mk" + } + } + def reactAndroidProjectDir = project(':ReactAndroid').projectDir + def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) { + dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck") + from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib") + into("$buildDir/react-ndk/exported") + } + def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) { + dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck") + from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib") + into("$buildDir/react-ndk/exported") + } + afterEvaluate { + // If you wish to add a custom TurboModule or component locally, + // you should uncomment this line. + // preBuild.dependsOn("generateCodegenArtifactsFromSchema") + preDebugBuild.dependsOn(packageReactNdkDebugLibs) + preReleaseBuild.dependsOn(packageReactNdkReleaseLibs) + + // Due to a bug inside AGP, we have to explicitly set a dependency + // between configureNdkBuild* tasks and the preBuild tasks. + // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732 + configureNdkBuildRelease.dependsOn(preReleaseBuild) + configureNdkBuildDebug.dependsOn(preDebugBuild) + reactNativeArchitectures().each { architecture -> + tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure { + dependsOn("preDebugBuild") + } + tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure { + dependsOn("preReleaseBuild") + } + } + } + } + splits { abi { reset() enable enableSeparateBuildPerCPUArchitecture universalApk false // If true, also generate a universal APK - include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" + include (*reactNativeArchitectures()) } } signingConfigs { @@ -156,11 +228,6 @@ android { buildTypes { debug { signingConfig signingConfigs.debug - if (nativeArchitectures) { - ndk { - abiFilters nativeArchitectures.split(',') - } - } } release { // Caution! In production, you need to generate your own keystore file. @@ -190,6 +257,7 @@ android { dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) + //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" // From node_modules @@ -209,14 +277,31 @@ dependencies { } if (enableHermes) { - def hermesPath = "../../node_modules/hermes-engine/android/"; - debugImplementation files(hermesPath + "hermes-debug.aar") - releaseImplementation files(hermesPath + "hermes-release.aar") + //noinspection GradleDynamicVersion + implementation("com.facebook.react:hermes-engine:+") { // From node_modules + exclude group:'com.facebook.fbjni' + } } else { implementation jscFlavor } } +if (isNewArchitectureEnabled()) { + // If new architecture is enabled, we let you build RN from source + // Otherwise we fallback to a prebuilt .aar bundled in the NPM package. + // This will be applied to all the imported transtitive dependency. + configurations.all { + resolutionStrategy.dependencySubstitution { + substitute(module("com.facebook.react:react-native")) + .using(project(":ReactAndroid")) + .because("On New Architecture we're building React Native from source") + substitute(module("com.facebook.react:hermes-engine")) + .using(project(":ReactAndroid:hermes-engine")) + .because("On New Architecture we're building Hermes from source") + } + } +} + // Run this once to be able to run the application with BUCK // puts all compile dependencies into folder libs for BUCK to use task copyDownloadableDepsToLibs(type: Copy) { @@ -225,3 +310,11 @@ task copyDownloadableDepsToLibs(type: Copy) { } apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) + +def isNewArchitectureEnabled() { + // To opt-in for the New Architecture, you can either: + // - Set `newArchEnabled` to true inside the `gradle.properties` file + // - Invoke gradle with `-newArchEnabled=true` + // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true` + return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" +} diff --git a/template/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.java b/template/template/android/app/src/debug/java/com/awesomeproject/ReactNativeFlipper.java similarity index 99% rename from template/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.java rename to template/template/android/app/src/debug/java/com/awesomeproject/ReactNativeFlipper.java index 8f18993f..8ed784fe 100644 --- a/template/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.java +++ b/template/template/android/app/src/debug/java/com/awesomeproject/ReactNativeFlipper.java @@ -5,6 +5,7 @@ * directory of this source tree. */ package com.helloworld; + import android.content.Context; import com.facebook.flipper.android.AndroidFlipperClient; import com.facebook.flipper.android.utils.FlipperUtils; @@ -23,15 +24,18 @@ import com.facebook.react.bridge.ReactContext; import com.facebook.react.modules.network.NetworkingModule; import okhttp3.OkHttpClient; + public class ReactNativeFlipper { public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { if (FlipperUtils.shouldEnableFlipper(context)) { final FlipperClient client = AndroidFlipperClient.getInstance(context); + client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); client.addPlugin(new ReactFlipperPlugin()); client.addPlugin(new DatabasesFlipperPlugin(context)); client.addPlugin(new SharedPreferencesFlipperPlugin(context)); client.addPlugin(CrashReporterPlugin.getInstance()); + NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); NetworkingModule.setCustomClientBuilder( new NetworkingModule.CustomClientBuilder() { @@ -42,6 +46,7 @@ public void apply(OkHttpClient.Builder builder) { }); client.addPlugin(networkFlipperPlugin); client.start(); + // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized // Hence we run if after all native modules have been initialized ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); @@ -65,4 +70,4 @@ public void run() { } } } -} \ No newline at end of file +} diff --git a/template/template/android/app/src/main/java/com/helloworld/MainActivity.java b/template/template/android/app/src/main/java/com/awesomeproject/MainActivity.java similarity index 98% rename from template/template/android/app/src/main/java/com/helloworld/MainActivity.java rename to template/template/android/app/src/main/java/com/awesomeproject/MainActivity.java index 405d80a8..4a9fae76 100644 --- a/template/template/android/app/src/main/java/com/helloworld/MainActivity.java +++ b/template/template/android/app/src/main/java/com/awesomeproject/MainActivity.java @@ -12,7 +12,7 @@ public class MainActivity extends ReactActivity { */ @Override protected String getMainComponentName() { - return "HelloWorld"; + return "helloworld"; } /** diff --git a/template/template/android/app/src/main/java/com/helloworld/MainApplication.java b/template/template/android/app/src/main/java/com/awesomeproject/MainApplication.java similarity index 100% rename from template/template/android/app/src/main/java/com/helloworld/MainApplication.java rename to template/template/android/app/src/main/java/com/awesomeproject/MainApplication.java diff --git a/template/template/android/app/src/main/java/com/helloworld/newarchitecture/MainApplicationReactNativeHost.java b/template/template/android/app/src/main/java/com/awesomeproject/newarchitecture/MainApplicationReactNativeHost.java similarity index 100% rename from template/template/android/app/src/main/java/com/helloworld/newarchitecture/MainApplicationReactNativeHost.java rename to template/template/android/app/src/main/java/com/awesomeproject/newarchitecture/MainApplicationReactNativeHost.java diff --git a/template/template/android/app/src/main/java/com/helloworld/newarchitecture/components/MainComponentsRegistry.java b/template/template/android/app/src/main/java/com/awesomeproject/newarchitecture/components/MainComponentsRegistry.java similarity index 100% rename from template/template/android/app/src/main/java/com/helloworld/newarchitecture/components/MainComponentsRegistry.java rename to template/template/android/app/src/main/java/com/awesomeproject/newarchitecture/components/MainComponentsRegistry.java diff --git a/template/template/android/app/src/main/java/com/helloworld/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java b/template/template/android/app/src/main/java/com/awesomeproject/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java similarity index 100% rename from template/template/android/app/src/main/java/com/helloworld/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java rename to template/template/android/app/src/main/java/com/awesomeproject/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java