This guide describes the changes necessary to migrate to version 5.0.
Gradle and Android Gradle Plugin updates
Upgrade Gradle and Android Gradle Plugin versions
First, upgrade your Gradle and Android Gradle Plugin versions. This upgrade includes better compatibility with certain SDK dependencies (including Kotlin 1.9), as well as some critical bug fixes.
This SDK major release requires the following version dependencies for your Android application project:
- a Gradle version at least v7.5.0 but no higher than v7.6.0.
- an Android Gradle Plugin (AGP) version in the range of v7.4.x.
You can target a higher version of the plugins; however, you might run into deprecation warnings, or some new features might not work.
To modify the Gradle version, modify the line in your project's
/gradle/wrapper/gradle-wrapper.properties
file
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
To modify the Android Gradle Plugin version, modify the build.gradle
file that
contains the buildscript
block. For example:
buildscript {
repositories {
google()
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.1'
}
}
Java 7 to Java 8 library support migration
Step 1 - Enable Java 8 library support
Since the SDK min API level is 23 and the required AGP version is 7.4+, the configuration is slightly different from the mentioned source documentation.
buildscript {
repositories {
google()
mavenCentral()
jcenter()
maven {
url = uri("https://storage.googleapis.com/r8-releases/raw")
}
}
dependencies {
classpath 'com.android.tools:r8:8.0.46'
classpath 'com.android.tools.build:gradle:7.4.1'
}
}
android {
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.3'
}
Step 2 - Migrate from Proguard or Dexguard to R8
AGP v7.4+ uses R8 as the default shrinking, obfuscation, and optimization tool for the binary, so no special action is needed at this point.
If the project is migrated from AGP 4.0+, AGP may issue a the following warnings about file removals:
useProguard true
usage inbuild.gradle
fileandroid.enableR8=false
usage ingradle.properties
file
Removing these lines usually resolves those issues.
Kotlin 1.6 to 1.9 migration
Step 1 - Migrate to Kotlin Gradle Plugin 1.9.0
Update the Kotlin Gradle Plugin version in your application top level module
build.gradle file. Make sure to add org.jetbrains.kotlin:kotlin-gradle-plugin
in the dependencies from the buildscript block in case it's missing.
buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0"
}
}
You must migrate your application from Kotlin-synthetics in case you're coming from Kotlin Gradle Plugin 1.6.X or 1.7.X. Refer to the official migration guide for more information.
Step 2 - Upgrade kotlin-stdlib to 1.9.0
Upgrade kotlin-stblib
to 1.9.0 in your application build.gradle file.
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.0"
}
Make sure to remove any references to kotlin-stdlib-jdk7
or
kotlin-stdlib-jdk8
. Both dependencies have been consolidated into
kotlin-stdlib
starting in Kotlin
1.8.0.
StatusListener deprecation
The StatusListener
interface is now deprecated (to be removed in v6), in favor
of DriverStatusListener
.
There are mainly 3 changes:
- Change the
implements
interface fromStatusListener
toDriverStatusListener
. - Add a
Nullable
cause
parameter toupdateStatus
. - Call the
DriverContextBuilder.setDriverStatusListener
instead of thesetStatusListener
.
DriverStatusListener
shares the same structure as StatusListener
. The main
difference between them is that DriverStatusListener.updateStatus()
takes an
extra parameter named cause
. This provides users insights on the cause of an
update with error status level.
Typically, you would use cause
to retrieve the error code returned by Fleet
Engine for failed location updates.
The following sample illustrates how to implement StatusListener
:
class MyStatusListener implements StatusListener {
/** Called when background status is updated during actions such as location reporting. */
@Override
public void updateStatus(
StatusLevel statusLevel, StatusCode statusCode, String statusMsg) {
// Implementation
}
}
// Inject StatusListener into DriverContext.
DriverContextBuilder.setStatusListener(new MyStatusListener());
The following shows a sample DriverStatusListener
implementation:
class MyStatusListener implements DriverStatusListener {
/** Called when background status is updated during actions such as location reporting. */
@Override
public void updateStatus(
StatusLevel statusLevel, StatusCode statusCode, String statusMsg, @Nullable Throwable cause) {
// Existing implementation
if (cause != null && cause instanceof StatusRuntimeException) {
if (Status.NOT_FOUND.getCode().equals(cause.getStatus().getCode())) {
// NOT_FOUND gRPC exception thrown by Fleet Engine.
}
}
}
}
DriverContextBuilder.setStatusListener(new MyStatusListener());
Implement DriverStatusListener
as a functional interface
DriverStatusListener
supports Java functional interfaces just like its
predecessor. Here is an example of it:
DriverContextBuilder.setDriverStatusListener((statusLevel, statusCode, statusMsg, cause) -> {
if (cause != null && cause instanceof StatusRuntimeException) {
if (Status.NOT_FOUND.getCode().equals(cause.getStatus().getCode())) {
// NOT_FOUND gRPC exception thrown by Fleet Engine.
}
}
});