React Native:将多个Maven URL匹配到特定的依赖项?

时间:2019-06-20 15:37:28

标签: maven react-native android-gradle build.gradle react-native-android

请不要将此标记为重复。我花了两天时间搜寻Github,Stack,Android Studio文档,RN文档和Gradle文档以寻找答案。

问题

我们的React Native项目无法在Android上构建。一项构建错误是

Could not find com.github.wix-playground:ahbottomnavigation:2.4.9

fix for this errormaven { url 'https://jitpack.io' }添加到项目build.gradle

但是,添加完之后,我们得到了第二个错误,即

Execution failed for task ':react-native-ble-plx:compileDebugJavaWithJavac'

The fix for thismaven { url 'https://maven.google.com' }添加到build.gradle

但是在添加了第二个修复程序之后,我们再次触发了第一个错误。

问题

是否有一种方法可以列出maven { <url> }中的两个build.gradle,而每个maven { <url> }仅用于依赖它的特定依赖项?

OR

我们可以在所有依赖项中强制使用相同的支持库版本吗?

  • 我从这些Gradle Docs中尝试了许多方法
  • 我已经尝试过此Stack Post
  • 中的答案
  • 我已更新到Android Studio 3.4.1

任何帮助将不胜感激。

我们的文件

项目级别build.gradle

buildscript {
    repositories {
        google()
        mavenLocal()
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.1'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
        mavenLocal()
        // maven { url 'https://maven.google.com' }
        maven { url 'https://jitpack.io' }     
        maven {
          url "$rootDir/../node_modules/react-native/android" // This URL still works
        }
    }
}
  ext {
        buildToolsVersion = "28.0.3"
        minSdkVersion = 19
        compileSdkVersion = 26
        targetSdkVersion = 26
        supportLibVersion = "28.0.0"
    }

    subprojects { subproject ->
    afterEvaluate {
        if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
            android {
                variantFilter { variant ->
                    def names = variant.flavors*.name
                    if (names.contains("reactNative51") || names.contains("reactNative56")) {
                        setIgnore(true)
                    }
                }
            }
        }
    }
}

app/build.gradle

buildscript {
    repositories {
        maven { url 'https://maven.fabric.io/public' }
    }
    dependencies {
        classpath 'io.fabric.tools:gradle:1.+'
    }
}

apply plugin: "com.android.application"
apply plugin: "io.fabric"
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"

repositories {
    maven { url 'https://maven.fabric.io/public' }
}

import com.android.build.OutputFile

project.ext.react = [
    entryFile: "index.js",
    bundleInStaging: true,
    devDisabledInStaging: true,
    inputExcludes: ["ios/**", "__tests__/**", "bundle_out/**"]
]

apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-sentry/sentry.gradle"

def enableSeparateBuildPerCPUArchitecture = false

def enableProguardInReleaseBuilds = false

def debugKeystorePropertiesFile = rootProject.file("keystores/debug.keystore.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(debugKeystorePropertiesFile))

def releaseKeystorePropertiesFile = rootProject.file("keystores/release.keystore.properties");
def releaseKeystoreProperties = new Properties()
releaseKeystoreProperties.load(new FileInputStream(releaseKeystorePropertiesFile))

android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'

    defaultConfig {
        applicationId "com.example"
        missingDimensionStrategy "RNN.reactNativeVersion", "reactNative55"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 177
        versionName "2.0.4"
        multiDexEnabled true
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
        manifestPlaceholders = [
            FABRIC_API_KEY: project.env.get("FABRIC_API_KEY"),
            FABRIC_SECRET: project.env.get("FABRIC_SECRET")
        ]
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    signingConfigs {
        debug {
            storeFile file(keystoreProperties['key.store'])
            storePassword keystoreProperties['key.store.password']
            keyAlias keystoreProperties['key.alias']
            keyPassword keystoreProperties['key.alias.password']
        }
        release {
            storeFile file(releaseKeystoreProperties['key.store'])
            storePassword releaseKeystoreProperties['key.store.password']
            keyAlias releaseKeystoreProperties['key.alias']
            keyPassword releaseKeystoreProperties['key.alias.password']
        }
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro", "proguard-devsupport.pro"
            testProguardFile 'proguard-debug.pro'
        }
        staging {
            signingConfig signingConfigs.debug
            matchingFallbacks = ['release', 'debug']
        }
        debug {
            signingConfig signingConfigs.debug
        }
    }
    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def versionCodes = ["armeabi-v7a":1, "x86":2]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }
        }
    }
}

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support' && requested.name != 'multidex') {
            details.useVersion "${rootProject.ext.supportLibVersion}"
        }
    }
}

dependencies {
    compile('com.google.android.gms:play-services-gcm:11.8.0') {
        force = true
    }
    compile project(':react-native-push-notification')
    implementation project(':react-native-awesome-card-io')
    implementation project(':react-native-fabric')
    implementation project(':react-native-randombytes')
    implementation project(':react-native-linear-gradient')
    implementation project(':react-native-spinkit')
    implementation project(':react-native-keychain')
    implementation project(':react-native-vector-icons')
    implementation project(':react-native-ble-plx')
    implementation project(':react-native-config')
    implementation project(':react-native-sentry')
    implementation project(':react-native-device-info')
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.0.0-alpha3'
    implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    implementation "com.android.support:appcompat-v7:27.1.0"
    implementation 'com.android.support:design:27.1.0'
    implementation "com.facebook.react:react-native:+"  // From node_modules
    implementation('com.crashlytics.sdk.android:crashlytics:2.9.3@aar') {
        transitive = true;
    }
    implementation project(':react-native-navigation')
    implementation project(':react-native-tcp')
    implementation 'com.android.support:design:25.4.0'
    implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    implementation 'com.android.support:multidex:1.0.3'
    implementation ('com.github.wix-playground:ahbottomnavigation:2.4.9') {
        exclude group: "com.android.support"
    }
}

task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <!-- < Only if you're using GCM or localNotificationSchedule() > -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <permission
        android:name="${applicationId}.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
    <!-- < Only if you're using GCM or localNotificationSchedule() > -->
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <application
      android:name="android.support.multidex.MultiDexApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:allowBackup="false"
      android:fullBackupContent="false"
      android:theme="@style/AppTheme">

        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name"
            android:value="YOUR NOTIFICATION CHANNEL NAME"/>
        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description"
            android:value="YOUR NOTIFICATION CHANNEL DESCRIPTION"/>
        <!-- Change the resource name to your App's accent color - or any other color you want -->
        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_color"
            android:resource="@android:color/white"/>

        <!-- < Only if you're using GCM or localNotificationSchedule() > -->
        <receiver
            android:name="com.google.android.gms.gcm.GcmReceiver"
            android:exported="true"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="${applicationId}" />
            </intent-filter>
        </receiver>
        <!-- < Only if you're using GCM or localNotificationSchedule() > -->

        <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
        <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
        <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/>

        <!-- < Only if you're using GCM or localNotificationSchedule() > -->
        <service
            android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>

      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustPan">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <meta-data
        android:name="io.fabric.ApiKey"
        android:value="${FABRIC_API_KEY}"
      />
      <meta-data
        android:name="io.fabric.ApiSecret"
        android:value="${FABRIC_SECRET}"
       />
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>

3 个答案:

答案 0 :(得分:1)

  

是否有一种方法可以在build.gradle中列出两个maven {},而每个maven {}仅用于依赖它的特定依赖项?

Matching repositories to dependencies是一个孵化功能。

当前,您可以检查official doc关于定义多个仓库的信息:

  

您可以定义多个资源库来解决依赖关系。如果某些依赖项仅在一个存储库中可用而在另一个存储库中不可用,则声明多个存储库会很有帮助。

     

声明的顺序决定了Gradle在运行时如何检查依赖关系。如果Gradle在特定存储库中找到模块描述符,它将尝试从同一存储库下载该模块的所有工件。您可以详细了解Gradle解析机制的内部运作方式。

  

我们可以在所有依赖项中强制使用相同的支持库版本吗?

您可以:

  • 从其中一个依赖项中排除冲突的模块/库
  • 明确声明支持库版本

例如: 例如:

  implementation "your dependency:$version" {
       exclude group: "org.xxxx.xxx", module: "xxxxxxx"
   }

例如:

android {
    configurations.all {
        resolutionStrategy.force 'com.android.support:support-xxxx:XX.YY.ZZ'
    }
}

请注意这种方法,因为您可能会在某些库中强制使用向后版本。

答案 1 :(得分:0)

我们使用了解决策略(请参见上面的评论)来解决我们的问题。另外,在我们的app/build.gradle中,我们决定不使用androidx支持库实现,而是使用较旧的com.android.support:xxx库。最后,解决方案看起来像这样。

app/build.gradle

// Force the same support library version across all dependencies
configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support' && requested.name != 'multidex') {
            details.useVersion "${rootProject.ext.supportLibVersion}"
        }
    }
}

implementation 'com.android.support:design:25.4.0'
implementation 'com.android.support:appcompatv7:${rootProject.ext.supportLibVersion}'

答案 2 :(得分:0)

使用此命令可以在单个命令中添加多个依赖项

all the cell of column_dataset_2_normalized

也请明智地使用本机版本

react-native init --version =“ react-native@0.36.0” MyNewApp

react-native初始化--version =“ react-native@0.59.8” MyNewAppName