项目搭建与依赖配置:Gradle 依赖、Room 注解处理器、WorkManager 初始化、Retrofit 集成

2.1 本章概述

搭建离线同步项目的第一步是将核心组件接入 Android 构建系统。本章围绕 Room、WorkManager、Retrofit 三者的 Gradle 依赖声明、注解处理器配置、WorkManager 初始化方式以及 Retrofit 实例的集成流程展开,并厘清各组件在离线同步架构中的职责边界。

组件职能一览
组件职责依赖声明(KTS 格式)
Room本地持久化、DAO 操作、离线缓存room-runtime + room-ktx
WorkManager后台同步调度、约束管理、链式任务work-runtime-ktx
Retrofit网络请求、REST API 封装、拦截器链retrofit + converter-gson

2.2 组件间依赖关系

下图展示了离线同步项目中各库的引用关系与初始化顺序。箭头方向表示“依赖”或“初始化触发”。

第2章 项目搭建与依赖关系图 📦 Gradle 依赖配置 🗄️ Room (数据库) ⏰ WorkManager 🌐 Retrofit 🔧 Room 注解处理器 ⚡ InitializationProvider 🔨 Retrofit.Builder ⚠️ 初始化顺序说明 WorkManager 自动初始化(或自定义)不与 Room/Retrofit 冲突,但建议在 Application.onCreate 中完成全部组件的 eager 初始化。

2.3 Gradle 依赖声明

在项目 build.gradle.kts(Module: app)中添加以下依赖。注意使用 KTS 脚本格式,版本号建议统一管理在 libs.versions.toml 中。

// app/build.gradle.kts
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.devtools.ksp") // 使用 KSP 代替 kapt(性能更好)
}

android {
    // ...
}

dependencies {
    // Room
    val roomVersion = "2.6.1"
    implementation("androidx.room:room-runtime:$roomVersion")
    implementation("androidx.room:room-ktx:$roomVersion")
    ksp("androidx.room:room-compiler:$roomVersion")  // 注解处理器

    // WorkManager
    val workVersion = "2.9.0"
    implementation("androidx.work:work-runtime-ktx:$workVersion")

    // Retrofit + Gson
    val retrofitVersion = "2.9.0"
    implementation("com.squareup.retrofit2:retrofit:$retrofitVersion")
    implementation("com.squareup.retrofit2:converter-gson:$retrofitVersion")
    implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
}
关键点:Room 注解处理器必须显式声明。如果使用 kapt,则改为 kapt("androidx.room:room-compiler:$roomVersion")。未配置注解处理器将导致 DAO 编译失败,报错如“cannot find symbol RoomDatabase”或“TypeConverter not processed”。

2.4 Room 注解处理器配置

Room 在编译期通过注解处理器生成数据库实现类(如 AppDatabase_Impl)。使用 KSP 时的额外配置:

// 在 app/build.gradle.kts 的 android 块中
android {
    ksp {
        arg("room.schemaLocation", "$projectDir/schemas")
        arg("room.incremental", "true")
    }
}

上述配置会导出数据库 schema 至 app/schemas 目录,便于版本迁移测试。增量编译可加快后续构建。

2.5 WorkManager 初始化方式

WorkManager 2.6+ 默认使用 自动初始化(ContentProvider 注册),无需手动调用。但如果需要自定义配置(如自定义网络状态监听、日志级别),需在 AndroidManifest.xml 中移除默认提供程序,并手动初始化。

方式一:默认自动初始化(推荐简单场景)

<!-- AndroidManifest.xml 无需额外配置 — 系统自动注册 ContentProvider -->

方式二:手动初始化(需要自定义配置时)

<!-- AndroidManifest.xml 中移除默认初始化 -->
<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <meta-data
        android:name="androidx.work.WorkManagerInitializer"
        android:value="androidx.startup"
        tools:node="remove" />
</provider>

然后在 Application.onCreate() 中通过 Configuration 构建:

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        val config = Configuration.Builder()
            .setMinimumLoggingLevel(android.util.Log.INFO)
            .setWorkerFactory(MyCustomWorkerFactory())
            .build()
        WorkManager.initialize(this, config)
    }
}
调试建议:在开发阶段将日志级别设为 Log.VERBOSE 或 Log.DEBUG,便于跟踪 WorkManager 的任务调度、约束判断和执行状态。

2.6 Retrofit 集成与网络层配置

Retrofit 实例通常在 Application 或依赖注入容器中单例创建。以下为标准配置:

// RetrofitClient.kt
import com.google.gson.GsonBuilder
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitClient {
    private const val BASE_URL = "https://api.example.com/"

    private val loggingInterceptor = HttpLoggingInterceptor().apply {
        level = HttpLoggingInterceptor.Level.BODY  // 调试阶段用 BODY,生产用 HEADERS 或 NONE
    }

    private val okHttpClient = OkHttpClient.Builder()
        .addInterceptor(loggingInterceptor)
        .connectTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
        .readTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
        .writeTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
        .build()

    private val gson = GsonBuilder()
        .setLenient()
        .create()

    val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build()
}

定义 API 接口:

interface ApiService {
    @GET("sync/items")
    suspend fun getItems(): List<Item>

    @POST("sync/items")
    suspend fun postItem(@Body item: Item): Response<Void>
}

2.7 常见错误与排查

错误现象可能原因解决方案
编译时 cannot find symbol AppDatabase_ImplRoom 注解处理器未配置或 kapt/ksp 插件未应用确认添加了 ksp("androidx.room:room-compiler:$version") 且模块应用了 KSP 插件
WorkManager 初始化崩溃:IllegalStateException: WorkManager is already initialized自动初始化与手动初始化冲突使用 AndroidManifest 中的 tools:node="remove" 禁用自动初始化
Retrofit 请求返回 java.net.SocketTimeoutException超时时间过短或网络不可用增大 OkHttp 超时时间或添加重试拦截器
依赖版本冲突(如 Kotlin 版本与 Room 不兼容)库版本未对齐使用 BOM 管理版本,或参考 AndroidX 版本映射

2.8 性能与稳定性优化备忘

  • 依赖精简:避免引入完整 Guava 库;Retrofit 可搭配 converter-scalars 替代 Gson 以降低包体积(若无需 JSON 序列化)。
  • OkHttp 连接池:单例 OkHttpClient 复用连接、降低延迟。
  • Room 增量编译:启用 room.incremental=true 减少二次构建时间。
  • WorkManager 惰性初始化:仅在第一次调用 WorkManager.getInstance(context) 时触发初始化,避免 Application 启动耗时增加。
  • 网络日志切面:在 BuildConfig.DEBUG 条件判断下添加 HttpLoggingInterceptor,发布版本自动移除。

2.9 配置验证小实验

执行以下命令验证 Gradle 依赖是否正确拉取:

./gradlew app:dependencies --configuration implementation | grep -E "(room|work|retrofit)"

输出应包含类似条目:

+--- androidx.room:room-runtime:2.6.1
+--- androidx.work:work-runtime-ktx:2.9.0
+--- com.squareup.retrofit2:retrofit:2.9.0

若缺少 Room 注解处理器,可检查 ksp 的配置:

./gradlew app:kspKotlinDebug --info | grep "room-compiler"

如输出版本号,则注解处理器已生效。

下一步建议:确认依赖无误后,即可进入第3章“定义 Room 数据库与 DAO”。本章配置是后续所有编码的基础,务必确保构建通过。