drmrbrewer
drmrbrewer

Reputation: 12999

OkHttp support for SDK versions less than 21

OkHttp has recently dropped support for Android 4, except via a separate 3.12.x branch that will be supported until end of Dec 2021 (and probably receive no more than critical updates or bugfixes).

On the assumption that you wish to continue to support Android 4, like I do, since 10% of the Android user base is still a significant proportion, and don't want to be stuck in a dead-end branch...

Rather than being stuck on the 3.12.x branch for all sdk versions, is there any way of using the 3.12 branch for sdk < 21 and the 3.13 branch for sdk >= 21, a bit like it would of course be possible to use HttpUrlConnection for sdk < 21 and OkHttp 3.13 for sdk >= 21?

Upvotes: 10

Views: 3695

Answers (1)

jerbob92
jerbob92

Reputation: 161

I actually created an example in the project that I created for NativeScript: nativescript-http

I wanted minSdk >= 21 to use OkHttp4 and minSdk > 17 && minSdk < 21 to use the LTS version: OkHttp 3.12. I'm using minSdk 17 because that's as low as NativeScript goes. But ofcourse you can go as low as OkHttp3 supports.

It wasn't as simple as just creating flavors for different minSdk versions, perhaps due to the way NativeScript handles dependencies by plugins. It took me half a day to figure out to do it, so I'm posting it here, it might help someone:

android {
  // ... other config.
  flavorDimensions "api"

  productFlavors {
    minApi21 {
      dimension "api"
      minSdkVersion 21
      versionNameSuffix "-minApi21"
    }

    minApi17 {
      dimension "api"
      minSdkVersion 17
      versionNameSuffix "-minApi17"
    }
  }
}

android.applicationVariants.all { variant ->
  if (variant.name.contains("minApi17")) {
    variant.getCompileConfiguration().resolutionStrategy.force "com.squareup.okhttp3:okhttp:3.12.+"
    variant.getRuntimeConfiguration().resolutionStrategy.force "com.squareup.okhttp3:okhttp:3.12.+"
  }

  variant.outputs.each { output ->
    if (variant.name.contains("minApi17")) {
      output.versionCodeOverride = 10000000 + variant.versionCode
    } else {
      output.versionCodeOverride = 20000000 + variant.versionCode
    }
  }
}

The part in android is to create 2 product flavors, one for minSdk 17, and one for minSdk 21.

The part in android.applicationVariants consists of two things:

  1. Making sure flavor minApi17 uses version 3.12.+ for minSdk 17
  2. Making sure that every flavor has it's own build versionCode. It takes the version from the manifest and does (10000000 + manifestVersionCode) for minApi17 and (20000000 + manifestVersionCode) for minApi21. This will create 2 APK's when you build a release, one for Android 4 (app-minApi17-release.apk), and one for Android 5 (app-minApi21-release.apk). You can also combine this with ABI splitting.

When you upload both APK's to the Playstore, Google will make sure the proper APK get's distributed to the different devices.

Upvotes: 2

Related Questions