Android 驱动程序 SDK 5.0 迁移指南

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

Gradle 和 Android Gradle 插件更新

升级 Gradle 和 Android Gradle 插件版本

首先,升级 Gradle 和 Android Gradle 插件版本。此次升级改进了与某些 SDK 依赖项(包括 Kotlin 1.9)的兼容性,并修复了一些重大问题。

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

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

您可以以更高版本的插件为目标平台;但是,您可能会遇到弃用警告,或者某些新功能可能无法正常运行。

如需修改 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 合成迁移应用。如需了解详情,请参阅官方迁移指南

第 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 接口现已废弃(将在 v6 中移除),取而代之的是 DriverStatusListener

主要有 3 项更改:

  1. implements 接口从 StatusListener 更改为 DriverStatusListener
  2. Nullable cause 参数添加到 updateStatus
  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.
    }
  }
});