NordicSemiconductor / Android-DFU-Library

Device Firmware Update library and Android app
http://www.nordicsemi.com/dfu
BSD 3-Clause "New" or "Revised" License
768 stars 272 forks source link

v1.8.0: Error: Program type already present: android.support.v4.app.LoaderManagerImpl #147

Closed eliotstock closed 5 years ago

eliotstock commented 5 years ago

In moving from v1.7.0 to v1.8.0, I get this error not at build time, but when first running/debugging the app in Android Studio:

AGPBI: {"kind":"error","text":"Program type already present: android.support.v4.app.LoaderManagerImpl","sources":[{}],"tool":"D8"}
> Task :app:buildInfoGeneratorDebug
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.
> com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
... many jar files ...
  Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes.
  Program type already present: android.support.v4.app.LoaderManagerImpl

Here's my app gradle file:

apply plugin: 'com.android.application'

repositories {
    google()
    mavenLocal()
    mavenCentral()
    maven {
        url 'http://google-api-client-libraries.appspot.com/mavenrepo'
    }
}

android {
    compileSdkVersion 28

    defaultConfig {
        applicationId "cc.biketracker.android"
        minSdkVersion 26
        targetSdkVersion 26
        versionCode 31
        versionName "31.0"

        // Required when more than 65K methods in the dex file. See:
        //   http://developer.android.com/tools/building/multidex.html
        multiDexEnabled = true
    }

    defaultConfig {
        // See: https://github.com/firebase/FirebaseUI-Android/blob/master/auth/README.md
        resConfigs "en"
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    // implementation fileTree(include: ['*.jar'], dir: 'libs')
    // implementation fileTree(include: ['*.zip'], dir: 'libs')

    implementation 'com.android.support.constraint:constraint-layout:1.1.3'

    // Google Play Services. Version number gets added to AndroidManifest.xml.
    implementation "com.google.android.gms:play-services-location:16.0.0"
    implementation "com.google.android.gms:play-services-maps:16.0.0"

    // Note that we don't explicitly pull in Google Play Services auth here. Let Firebase pull it in to avoid any version mismatch.
    // implementation "com.google.android.gms:play-services-auth:16.0.1"

    // Firebase
    implementation "com.google.firebase:firebase-core:16.0.5"
    implementation "com.google.firebase:firebase-database:16.0.4"
    implementation 'com.google.firebase:firebase-firestore:17.1.2'
    implementation "com.google.firebase:firebase-crash:16.2.1"
    implementation "com.google.firebase:firebase-messaging:17.3.4"
    implementation "com.google.firebase:firebase-storage:16.0.4"

    // Firebase UI
    implementation 'com.firebaseui:firebase-ui-auth:4.2.1'
    // This will also pull in:
    //   "com.google.firebase:firebase-auth:16.0.5"
    // which will then pull in:
    //   "com.google.android.gms:play-services-auth:16.0.1"

    // Google Services (not Google Play Services) required for FCM
    implementation 'com.google.gms:google-services:4.2.0'

    // GSON
    implementation 'com.google.code.gson:gson:2.8.5'

    // Joda time
    implementation 'joda-time:joda-time:2.8'

    // Apache Commons Lang
    implementation 'org.apache.commons:commons-lang3:3.3.2'

    // Apache Commons IO
    implementation "commons-io:commons-io:2.6"

    // Nordic's BLE library
    implementation 'no.nordicsemi.android:ble:2.0.0'

    // Nordic's DFU library
    implementation 'no.nordicsemi.android:dfu:1.8.0'
}

// This needs to come after our dependencies{} block when we're using Firebase or later versions of
// Google Play Services.
apply plugin: 'com.google.gms.google-services'

I noticed you bumped your gradle version in 1.8.0, so I changed mine to match yours (4.10.2) but that didn't help. Can you see anything wrong here? Is there a new dependency between the bLE library and the DFU library or vice versa?

alixwar commented 5 years ago

I'm not involved in developing the DFU library but I find it odd that you have set targetSdkVersion to the same value as minSdkVersion but have set a higher compileSdkVersion (https://medium.com/androiddevelopers/picking-your-compilesdkversion-minsdkversion-targetsdkversion-a098a0341ebd).

Also make sure that you are using at least version 3.1.0 of the Android Gradle Plugin (see: https://developer.android.com/studio/releases/gradle-plugin)

philips77 commented 5 years ago

Hi @eliotstock, No, the DFU lib is not dependent on BLE library. It's much older, I'd have to rewrite everything. I would say that the issue is related to importing multiple versions of support library. DFU uses support-core-utils:28.0.0 and your google services may use different. You may run gradle task: help:dependencies for your app module. It will list all dependencies:

archives - Configuration for archive artifacts.
+--- com.android.support:support-core-utils:28.0.0
|    +--- com.android.support:support-annotations:28.0.0
|    +--- com.android.support:support-compat:28.0.0
|    |    +--- com.android.support:support-annotations:28.0.0
|    |    +--- com.android.support:collections:28.0.0
|    |    |    \--- com.android.support:support-annotations:28.0.0
|    |    +--- android.arch.lifecycle:runtime:1.1.1
|    |    |    +--- android.arch.lifecycle:common:1.1.1
|    |    |    |    \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    |    +--- android.arch.core:common:1.1.1
|    |    |    |    \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
[...]

All should finally use the same version, as above. lifecycleruntime uses annotations:26.1.0, but they are switched to 28.0.0. If you find any older without ->, then add it explicitly to your dependencies. I'm doing it here: https://github.com/NordicSemiconductor/Android-nRF-Toolbox/blob/develop/wear/build.gradle#L44. Try adding android-support-v4:28.0.0. Gradle version should not matter.

eliotstock commented 5 years ago

OK, thanks. I tried adding this:

implementation 'com.android.support:support-v4:28.0.0'

But got this error in the gradle lint even before building:

All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). Found versions 28.0.0, 27.1.1. Examples include com.android.support:collections:28.0.0 and com.android.support:animated-vector-drawable:27.1.

It's Firebase and com.google.android.gms:play-services-location that are pulling in 28.0.0.

philips77 commented 5 years ago

Just add more dependencies:

implementation 'com.android.support:collections:28.0.0'
implementation 'com.android.support:animated-vector-drawable:28.0.0'

etc.

eliotstock commented 5 years ago

Oh I see, thanks. That's fixed it. My full list in the end is:

implementation 'no.nordicsemi.android:dfu:1.8.0'
implementation 'com.android.support:animated-vector-drawable:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:collections:28.0.0'
implementation 'com.android.support:customtabs:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
lisumac commented 5 years ago

i have added all the dependencies in my build gradle but I am getting the same error

philips77 commented 5 years ago

Did you follow this comment: https://github.com/NordicSemiconductor/Android-DFU-Library/issues/147#issuecomment-437799520