1apply plugin: "com.android.application" 2 3import com.android.build.OutputFile 4import groovy.json.JsonSlurper 5 6/** 7 * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 8 * and bundleReleaseJsAndAssets). 9 * These basically call `react-native bundle` with the correct arguments during the Android build 10 * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 11 * bundle directly from the development server. Below you can see all the possible configurations 12 * and their defaults. If you decide to add a configuration block, make sure to add it before the 13 * `apply from: "../../node_modules/react-native/react.gradle"` line. 14 * 15 * project.ext.react = [ 16 * // the name of the generated asset file containing your JS bundle 17 * bundleAssetName: "index.android.bundle", 18 * 19 * // the entry file for bundle generation. If none specified and 20 * // "index.android.js" exists, it will be used. Otherwise "index.js" is 21 * // default. Can be overridden with ENTRY_FILE environment variable. 22 * entryFile: "index.android.js", 23 * 24 * // https://reactnative.dev/docs/performance#enable-the-ram-format 25 * bundleCommand: "ram-bundle", 26 * 27 * // whether to bundle JS and assets in debug mode 28 * bundleInDebug: false, 29 * 30 * // whether to bundle JS and assets in release mode 31 * bundleInRelease: true, 32 * 33 * // whether to bundle JS and assets in another build variant (if configured). 34 * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 35 * // The configuration property can be in the following formats 36 * // 'bundleIn${productFlavor}${buildType}' 37 * // 'bundleIn${buildType}' 38 * // bundleInFreeDebug: true, 39 * // bundleInPaidRelease: true, 40 * // bundleInBeta: true, 41 * 42 * // whether to disable dev mode in custom build variants (by default only disabled in release) 43 * // for example: to disable dev mode in the staging build type (if configured) 44 * devDisabledInStaging: true, 45 * // The configuration property can be in the following formats 46 * // 'devDisabledIn${productFlavor}${buildType}' 47 * // 'devDisabledIn${buildType}' 48 * 49 * // the root of your project, i.e. where "package.json" lives 50 * root: "../../", 51 * 52 * // where to put the JS bundle asset in debug mode 53 * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 54 * 55 * // where to put the JS bundle asset in release mode 56 * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 57 * 58 * // where to put drawable resources / React Native assets, e.g. the ones you use via 59 * // require('./image.png')), in debug mode 60 * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 61 * 62 * // where to put drawable resources / React Native assets, e.g. the ones you use via 63 * // require('./image.png')), in release mode 64 * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 65 * 66 * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 67 * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 68 * // date; if you have any other folders that you want to ignore for performance reasons (gradle 69 * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 70 * // for example, you might want to remove it from here. 71 * inputExcludes: ["android/**", "ios/**"], 72 * 73 * // override which node gets called and with what additional arguments 74 * nodeExecutableAndArgs: ["node"], 75 * 76 * // supply additional arguments to the packager 77 * extraPackagerArgs: [] 78 * ] 79 */ 80 81project.ext.react = [ 82 entryFile: "index.js", 83 enableHermes: true, // clean and rebuild if changing 84 hermesCommand: '../../node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc' 85] 86 87apply from: "../../node_modules/react-native/react.gradle" 88 89/** 90 * Set this to true to create two separate APKs instead of one: 91 * - An APK that only works on ARM devices 92 * - An APK that only works on x86 devices 93 * The advantage is the size of the APK is reduced by about 4MB. 94 * Upload all the APKs to the Play Store and people will download 95 * the correct one based on the CPU architecture of their device. 96 */ 97def enableSeparateBuildPerCPUArchitecture = false 98 99/** 100 * Run Proguard to shrink the Java bytecode in release builds. 101 */ 102def enableProguardInReleaseBuilds = false 103 104/** 105 * The preferred build flavor of JavaScriptCore. 106 * 107 * For example, to use the international variant, you can use: 108 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 109 * 110 * The international variant includes ICU i18n library and necessary data 111 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 112 * give correct results when using with locales other than en-US. Note that 113 * this variant is about 6MiB larger per architecture than default. 114 */ 115def jscFlavor = 'org.webkit:android-jsc:+' 116 117/** 118 * Whether to enable the Hermes VM. 119 * 120 * This should be set on project.ext.react and that value will be read here. If it is not set 121 * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode 122 * and the benefits of using Hermes will therefore be sharply reduced. 123 */ 124def enableHermes = project.ext.react.get("enableHermes", false); 125 126/** 127 * Architectures to build native code for. 128 */ 129def reactNativeArchitectures() { 130 def value = project.getProperties().get("reactNativeArchitectures") 131 return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] 132} 133 134def keystoreProperties = new Properties() 135def keystorePropertiesFile = rootProject.file('keystore.properties') 136if (keystorePropertiesFile.exists()) { 137 keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) 138} 139 140def getVersion() { 141 def inputFile = new File("../package.json") 142 def packageJson = new JsonSlurper().parseText(inputFile.text) 143 return packageJson["version"] 144} 145 146def appVersion = getVersion() 147 148 149android { 150 ndkVersion rootProject.ext.ndkVersion 151 152 compileSdkVersion rootProject.ext.compileSdkVersion 153 154 defaultConfig { 155 applicationId "fun.upup.musicfree" 156 minSdkVersion rootProject.ext.minSdkVersion 157 targetSdkVersion rootProject.ext.targetSdkVersion 158 versionCode 1 159 versionName appVersion 160 buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() 161 162 if (isNewArchitectureEnabled()) { 163 // We configure the NDK build only if you decide to opt-in for the New Architecture. 164 externalNativeBuild { 165 ndkBuild { 166 arguments "APP_PLATFORM=android-21", 167 "APP_STL=c++_shared", 168 "NDK_TOOLCHAIN_VERSION=clang", 169 "GENERATED_SRC_DIR=$buildDir/generated/source", 170 "PROJECT_BUILD_DIR=$buildDir", 171 "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", 172 "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build", 173 "NODE_MODULES_DIR=$rootDir/../node_modules" 174 cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1" 175 cppFlags "-std=c++17" 176 // Make sure this target name is the same you specify inside the 177 // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable. 178 targets "musicfree_appmodules" 179 } 180 } 181 if (!enableSeparateBuildPerCPUArchitecture) { 182 ndk { 183 abiFilters (*reactNativeArchitectures()) 184 } 185 } 186 } 187 } 188 189 if (isNewArchitectureEnabled()) { 190 // We configure the NDK build only if you decide to opt-in for the New Architecture. 191 externalNativeBuild { 192 ndkBuild { 193 path "$projectDir/src/main/jni/Android.mk" 194 } 195 } 196 def reactAndroidProjectDir = project(':ReactAndroid').projectDir 197 def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) { 198 dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck") 199 from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib") 200 into("$buildDir/react-ndk/exported") 201 } 202 def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) { 203 dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck") 204 from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib") 205 into("$buildDir/react-ndk/exported") 206 } 207 afterEvaluate { 208 // If you wish to add a custom TurboModule or component locally, 209 // you should uncomment this line. 210 // preBuild.dependsOn("generateCodegenArtifactsFromSchema") 211 preDebugBuild.dependsOn(packageReactNdkDebugLibs) 212 preReleaseBuild.dependsOn(packageReactNdkReleaseLibs) 213 214 // Due to a bug inside AGP, we have to explicitly set a dependency 215 // between configureNdkBuild* tasks and the preBuild tasks. 216 // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732 217 configureNdkBuildRelease.dependsOn(preReleaseBuild) 218 configureNdkBuildDebug.dependsOn(preDebugBuild) 219 reactNativeArchitectures().each { architecture -> 220 tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure { 221 dependsOn("preDebugBuild") 222 } 223 tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure { 224 dependsOn("preReleaseBuild") 225 } 226 } 227 } 228 } 229 230 splits { 231 abi { 232 reset() 233 enable enableSeparateBuildPerCPUArchitecture 234 universalApk false // If true, also generate a universal APK 235 include (*reactNativeArchitectures()) 236 } 237 } 238 signingConfigs { 239 debug { 240 storeFile file('debug.keystore') 241 storePassword 'android' 242 keyAlias 'androiddebugkey' 243 keyPassword 'android' 244 } 245 release { 246 storeFile file(keystoreProperties['RELEASE_STORE_FILE']) 247 storePassword keystoreProperties['RELEASE_STORE_PASSWORD'] 248 keyAlias keystoreProperties['RELEASE_KEY_ALIAS'] 249 keyPassword keystoreProperties['RELEASE_KEY_PASSWORD'] 250 251 } 252 } 253 buildTypes { 254 debug { 255 signingConfig signingConfigs.debug 256 } 257 release { 258 // Caution! In production, you need to generate your own keystore file. 259 // see https://reactnative.dev/docs/signed-apk-android. 260 signingConfig signingConfigs.release 261 minifyEnabled enableProguardInReleaseBuilds 262 proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 263 } 264 } 265 266 // applicationVariants are e.g. debug, release 267 applicationVariants.all { variant -> 268 variant.outputs.each { output -> 269 // For each separate APK per architecture, set a unique version code as described here: 270 // https://developer.android.com/studio/build/configure-apk-splits.html 271 // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc. 272 def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] 273 def abi = output.getFilter(OutputFile.ABI) 274 if (abi != null) { // null for the universal-debug, universal-release variants 275 output.versionCodeOverride = 276 defaultConfig.versionCode * 1000 + versionCodes.get(abi) 277 } 278 279 } 280 } 281} 282 283dependencies { 284 implementation fileTree(dir: "libs", include: ["*.jar"]) 285 286 //noinspection GradleDynamicVersion 287 implementation "com.facebook.react:react-native:+" // From node_modules 288 289 implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" 290 implementation "androidx.core:core-splashscreen:1.0.0" 291 292 debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { 293 exclude group:'com.facebook.fbjni' 294 } 295 296 debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { 297 exclude group:'com.facebook.flipper' 298 exclude group:'com.squareup.okhttp3', module:'okhttp' 299 } 300 301 debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { 302 exclude group:'com.facebook.flipper' 303 } 304 305 if (enableHermes) { 306 //noinspection GradleDynamicVersion 307 implementation("com.facebook.react:hermes-engine:+") { // From node_modules 308 exclude group:'com.facebook.fbjni' 309 } 310 } else { 311 implementation jscFlavor 312 } 313 314 implementation project(':react-native-fs') 315 implementation 'com.facebook.fresco:animated-gif:2.5.0' 316 // https://mvnrepository.com/artifact/net.jthink/jaudiotagger 317 implementation 'net.jthink:jaudiotagger:2.2.5' 318 319} 320 321if (isNewArchitectureEnabled()) { 322 // If new architecture is enabled, we let you build RN from source 323 // Otherwise we fallback to a prebuilt .aar bundled in the NPM package. 324 // This will be applied to all the imported transtitive dependency. 325 configurations.all { 326 resolutionStrategy.dependencySubstitution { 327 substitute(module("com.facebook.react:react-native")) 328 .using(project(":ReactAndroid")) 329 .because("On New Architecture we're building React Native from source") 330 substitute(module("com.facebook.react:hermes-engine")) 331 .using(project(":ReactAndroid:hermes-engine")) 332 .because("On New Architecture we're building Hermes from source") 333 } 334 } 335} 336 337// Run this once to be able to run the application with BUCK 338// puts all compile dependencies into folder libs for BUCK to use 339task copyDownloadableDepsToLibs(type: Copy) { 340 from configurations.implementation 341 into 'libs' 342} 343 344apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 345 346apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle"); 347 348def isNewArchitectureEnabled() { 349 // To opt-in for the New Architecture, you can either: 350 // - Set `newArchEnabled` to true inside the `gradle.properties` file 351 // - Invoke gradle with `-newArchEnabled=true` 352 // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true` 353 return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" 354} 355 356