Detaching should fix the Android support library versions?

Hi,

I’m not an expert Android developer but I had some troubles in my detached app after detaching and adding Intercom + OneSignal.

I’d like to provide feedback on what kind of issue I have encountered and how it may be prevented by the Expo team for future developers.

Most of my problems have been related using different android support library versions:

First, I got some troubles to add “react-native-intercom” in v9.0.0 due to manifest merging error (probably solvable easily for any android develop).
It was actually working with 8.1.0 so I downgraded, but I just discovered it can also be solved by using same support library versions.

Then I got runtime crashes while opening Intercom in my app, because of version mismatch too.

java.lang.NoSuchMethodError: No static method getScreenWidthDp(Landroid/content/res/Resources;)I in class Landroid/support/v4/content/res/ConfigurationHelper; or its super classes (declaration of ‘android.support.v4.content.res.ConfigurationHelper’ appears in /data/app/com.xyz-1/split_lib_dependencies_apk.apk:classes3.dex)

So, it looks like it’s very important to fix these android support library versions.
Even Android Studio shows you a warning about that.

By default when you eject, there’s in build.gradle an hardcoded support library version:

compile ‘com.android.support:appcompat-v7:26.0.1’

Just after ejecting, we can see the Expo ejected project on Android Studio does warn about version mismatch.

I don’t know what is the best solution, but I think it makes sense for the Expo team to ensure that the newly detached Expo project does not use different support library versions by default.

As I’m not an Android expert it’s a bit hard for me to understand which version of SDK, buildTools and support library I’m supposed to use after ejecting (official RN doc seems on v23 and does not mention it’s safe to upgrade, but I guess it is because RN libraries are using more recent versions)

We discussed on Slack with @sibeliusseraphini and it seems having this config in root build.gradle does solve my pain points. Maybe a similar solution could be included by default on all Expo ejected projects?

ext {
  compileSdkVersion = 26
  buildToolsVersion = '26.0.2'
  supportlib_version = '26.0.2'
}

subprojects { subproject ->
  afterEvaluate{
    if((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
      android {
        compileSdkVersion rootProject.ext.compileSdkVersion
        buildToolsVersion rootProject.ext.buildToolsVersion
      }
    }
  }
  // See https://stackoverflow.com/a/42718231/82609
  project.configurations.all {
    resolutionStrategy.eachDependency { details ->
      if (details.requested.group == 'com.android.support'
              && !details.requested.name.contains('multidex')) {
        details.useVersion "$supportlib_version"
      }
    }
  }
}

Thank you for this insight, android building is a bit involved.

1 Like

hey, just wanted to drive some attention on this again.

The trick above would probably make life easier by defualt for many android developers after ejecting, and is actually documented in many places, including official android doc: Gradle tips and recipes  |  Android Developers

There are even RN libraries reading directly from ext, like OneSignal: https://github.com/geektimecoil/react-native-onesignal/blob/master/android/build.gradle#L3

cc @ccheever