Android 驱动程序 SDK 5.0 迁移指南

本指南介绍了迁移到版本 5.0 所需的更改。

Gradle 和 Android Gradle 插件更新

升级 Gradle 和 Android Gradle 插件版本

首先,升级 Gradle 和 Android Gradle 插件版本。此升级版本可更好地兼容某些 SDK 依赖项(包括 Kotlin 1.9),并修复了一些严重 bug。

此 SDK 主要版本需要您的 Android 应用项目具有以下版本依赖项:

  • Gradle 版本至少为 v7.5.0,但不高于 v7.6.0。
  • Android Gradle 插件 (AGP) 版本在 v7.4.x 范围内。

您可以定位到更高版本的插件;不过,您可能会遇到弃用警告,或者某些新功能可能无法正常运行。

如需修改 Gradle 版本,请修改项目 /gradle/wrapper/gradle-wrapper.properties 文件中的相应行

distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip

如需修改 Android Gradle 插件版本,请修改包含 buildscript 代码块的 build.gradle 文件。例如:

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

从 Java 7 迁移到 Java 8 库支持

第 1 步 - 启用 Java 8 库支持

来源

由于 SDK 的最低 API 级别为 23,且所需的 AGP 版本为 7.4 及更高版本,因此配置与上述源文档略有不同。

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'
}

第 2 步 - 从 Proguard 或 Dexguard 迁移到 R8

R8,来源

AGP v7.4 及更高版本使用 R8 作为二进制文件的默认缩减、混淆和优化工具,因此目前无需执行任何特殊操作。

如果项目是从 AGP 4.0 及更高版本迁移的,AGP 可能会发出以下有关文件移除的警告:

  • build.gradle 文件中的 useProguard true 用量
  • gradle.properties 文件中的 android.enableR8=false 用量

移除这些行通常可以解决相应问题。

从 Kotlin 1.6 迁移到 1.9

第 1 步 - 迁移到 Kotlin Gradle 插件 1.9.0

来源

更新应用顶级模块 build.gradle 文件中的 Kotlin Gradle 插件版本。确保在 buildscript 块的依赖项中添加 org.jetbrains.kotlin:kotlin-gradle-plugin(如果缺少)。

buildscript {
  dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0"
  }
}

如果您使用的是 Kotlin Gradle 插件 1.6.X 或 1.7.X,则必须迁移应用,使其不再使用 Kotlin-synthetics。如需了解详情,请参阅官方迁移指南

第 2 步 - 将 kotlin-stdlib 升级到 1.9.0

来源

在应用 build.gradle 文件中将 kotlin-stblib 升级到 1.9.0。

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.0"
}

请务必移除对 kotlin-stdlib-jdk7kotlin-stdlib-jdk8 的所有引用。从 Kotlin 1.8.0 开始,这两个依赖项已合并到 kotlin-stdlib 中。

StatusListener 弃用

StatusListener 接口现已弃用(将在 v6 中移除),取而代之的是 DriverStatusListener

主要有 3 项变更:

  1. implements 接口从 StatusListener 更改为 DriverStatusListener
  2. updateStatus 添加 Nullable cause 参数。
  3. 调用 DriverContextBuilder.setDriverStatusListener,而不是 setStatusListener

DriverStatusListenerStatusListener 具有相同的结构。它们之间的主要区别在于 DriverStatusListener.updateStatus() 采用了一个名为 cause 的额外形参。这可让用户深入了解状态为“错误”的更新的原因。

通常,您会使用 cause 检索 Fleet Engine 针对失败的位置更新返回的错误代码。

以下示例说明了如何实现 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());

以下展示了一个 DriverStatusListener 实现示例:

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());

DriverStatusListener 实现为功能接口

DriverStatusListener 支持 Java 函数式接口,就像其前身一样。示例如下:

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.
    }
  }
});