Skip to content

TechStack

lingion edited this page Sep 12, 2026 · 1 revision

技术栈与构建

一句话 TL;DR:这页列出 Sleepy 用的语言、框架、依赖版本和构建配置,并说明 CI 在做什么,给想本地编译或参与贡献的开发者看。

技术栈一览

组件 选型 版本
语言 Kotlin 2.1.10(随插件版本)
构建工具 Gradle Wrapper 9.3.1
Android Gradle Plugin AGP 9.1.0
UI 框架 Jetpack Compose 由 BOM 2024.10.00 统一管理
数据库 Room 2.7.0
注解处理 KSP 2.1.10-1.0.29
序列化 kotlinx.serialization JSON 1.6.3
Widget 层 RemoteViews + Canvas bitmap —

插件版本声明在根 build.gradle.kts:2-5;Gradle 发行版来自腾讯镜像,固定 9.3.1(gradle/wrapper/gradle-wrapper.properties:3)。

依赖与版本管理

仓库没有版本目录(gradle/libs.versions.toml 不存在),所有依赖版本直接写在 app/build.gradle.kts 的 dependencies 块里。模块只有一个::app(settings.gradle.kts:31)。

仓库源配置有两条优先级:

  • 插件仓库(pluginManagement)先走阿里云镜像(google/public/gradle-plugin 三个),再落到官方 google/mavenCentral/gradlePluginPortal;google 仓库还用 includeGroupByRegex 限定只接受 com.android.*、com.google.*、androidx.* 三个组(settings.gradle.kts:3-12)。
  • 依赖仓库(dependencyResolutionManagement)设为 PREFER_SETTINGS,同样阿里云镜像在前,末尾保留 jitpack.io——注释写明 compose-markdown(com.github.jeziellago)只在 JitPack 发布,当前 app/build.gradle.kts 里没有引用这个库(settings.gradle.kts:18-27)。

工程名是 WakeUpPure(settings.gradle.kts:30),根 gradle.properties 只有一行 android.disallowKotlinSourceSets=false。

Android SDK 与 Compose 配置

核心参数全部在 app/build.gradle.kts:9-22:

  • namespace 与 applicationId 均为 com.lingion.sleepy
  • compileSdk = 37,minSdk = 26,targetSdk = 37
  • versionCode = 58,versionName = "1.0.54"
  • vectorDrawables.useSupportLibrary = true
  • 语言资源过滤(localeFilters)只打包 5 种:zh-rCN、zh-rTW、en、ja、es

Compose 侧:buildFeatures 开启 compose 与 buildConfig(app/build.gradle.kts:46-49);Java 与 Kotlin 统一 17(app/build.gradle.kts:41-44、79-81)。编译器 opt-in 了 5 个实验 API:kotlin.RequiresOptIn、ExperimentalMaterial3Api、ExperimentalFoundationApi、ExperimentalAnimationApi、ExperimentalCoroutinesApi(app/build.gradle.kts:82-88)。

其余配置:打包时排除 META-INF 下的许可证类资源(app/build.gradle.kts:51-60);单元测试开启 isIncludeAndroidResources 与 isReturnDefaultValues(app/build.gradle.kts:62-67)。

构建变体与签名

buildTypes 只有两个(app/build.gradle.kts:24-39):

变体 行为
debug 不做 minify,versionName 追加 -debug 后缀
release isMinifyEnabled = true,套 proguard-android-optimize.txt + proguard-rules.pro,签名用 debug keystore(signingConfig = signingConfigs.getByName("debug"))

release 的 R8 策略是「只裁剪不改名」:app/proguard-rules.pro:5 一行 -dontobfuscate 关掉混淆,避免 Room 生成类和 serialization 反射因改名崩溃。keep 规则覆盖 kotlinx.serialization companion/serializer(app/proguard-rules.pro:12-21)、Room entity/DAO(app/proguard-rules.pro:23-27)、WorkManager(app/proguard-rules.pro:29-31)、Manifest 反射实例化的 AppWidgetProvider 与 BroadcastReceiver 子类(app/proguard-rules.pro:33-37)、WakeUp 课表兼容 schema 的 com.wakeup.pure.**(app/proguard-rules.pro:39-40)。

ABI 拆分已启用:产出 arm64-v8a、armeabi-v7a、x86_64 三个 ABI 的独立 APK,isUniversalApk = false 表示不生成通用包(app/build.gradle.kts:69-76)。

依赖清单

Compose 系列由 BOM 统一管理版本(app/build.gradle.kts:93-95),以下为主要依赖及版本:

依赖 版本 证据
androidx.compose:compose-bom 2024.10.00 app/build.gradle.kts:93
androidx.core:core-ktx 1.17.0 app/build.gradle.kts:107
androidx.activity:activity-compose 1.9.3 app/build.gradle.kts:108
androidx.lifecycle:* (runtime-ktx / viewmodel-compose / process) 2.8.7 app/build.gradle.kts:109-111
androidx.navigation:navigation-compose 2.8.3 app/build.gradle.kts:114
androidx.datastore:datastore-preferences 1.1.1 app/build.gradle.kts:117
androidx.room (runtime / ktx / compiler) 2.7.0,经 KSP 接入 app/build.gradle.kts:120-123
kotlinx-coroutines (core / android) 1.8.1 app/build.gradle.kts:126-127
kotlinx-serialization-json 1.6.3 app/build.gradle.kts:130
org.jsoup:jsoup 1.18.1 app/build.gradle.kts:133
androidx.work:work-runtime-ktx 2.9.1 app/build.gradle.kts:137
androidx.core:core-splashscreen 1.0.1 app/build.gradle.kts:140
io.coil-kt:coil-compose 2.7.0 app/build.gradle.kts:143

Compose 子件含 ui、ui-graphics、ui-tooling-preview、material3、material-icons-extended、animation、foundation(app/build.gradle.kts:97-104),版本全部跟随 BOM。

测试依赖:junit 4.13.2、junit-jupiter-params 5.10.2、org.json 20231013、sqlite-jdbc 3.53.4.0(用于直接执行 Room 迁移语句,仓库没有 Robolectric/Instrumentation 测试依赖)(app/build.gradle.kts:146-151);androidTest 有 androidx.test.ext:junit 1.2.1、espresso-core 3.6.1 和 BOM 管理的 ui-test-junit4(app/build.gradle.kts:152-156)。

Glance 去哪了

Glance 不在依赖列表里。构建文件里的注释写明:「Glance 依赖已随死代码删除移除……5 个生产 widget 全走 RemoteViews + Canvas bitmap」(app/build.gradle.kts:135-137)。widget 相关实现都在 app/src/main/java/com/lingion/sleepy/widget/ 目录,入口类如 WeekListWidget.kt、WeekGridWidgetProvider.kt、TodayWidget.kt。想看 widget 细节,转到 桌面组件。

CI Workflow

.github/workflows/ 下只有两个文件,做的是同一件事:把 GitHub 的仓库与 Release 镜像到 Gitee。没有任何 workflow 执行编译、测试或打包。

sync-to-gitee.yml

  • 触发条件:push 到任意分支、任意 tag、release published/edited,外加手动 workflow_dispatch(.github/workflows/sync-to-gitee.yml:3-9)
  • 两个 job 串行:sync-git 用 git clone --mirror 拉全量再 git push --mirror 到 Gitee,推之前会清掉 refs/pull 引用,失败按 15 秒间隔重试 3 次(.github/workflows/sync-to-gitee.yml:16-32);sync-release 只在 release 事件或手动触发时跑,超时上限 180 分钟(.github/workflows/sync-to-gitee.yml:34-38)
  • sync-release 是一段内嵌 Python:对照 GitHub Release 全量清单,在 Gitee 1 GB 附件配额内维护一个 980 MB 的滚动保留窗口——新版本优先占位,窗口外的旧版本只同步元数据不上传附件(.github/workflows/sync-to-gitee.yml:180-203);源码压缩包(-source.zip/-source.tar.gz)直接跳过,Gitee 页面会自动生成(.github/workflows/sync-to-gitee.yml:249-252);配额满了先淘汰最旧的非保护版本附件再重试一次(.github/workflows/sync-to-gitee.yml:138-177)

healer-gitee.yml

  • 触发条件:手动 workflow_dispatch + 定时 cron 23 */2 * * *,即每 2 小时一次(.github/workflows/healer-gitee.yml:3-5)
  • 职责:对比 GitHub 与 Gitee 双方的 release 附件清单,补传缺失文件;新版本排在队首优先补;同样遵守 980 MB 预算,配额满时淘汰已完整同步的最旧版本(.github/workflows/healer-gitee.yml:126-143、90-124)
  • 自带时间护栏:30 分钟后不再启动新的下载/上传,50 分钟强制收尾退出,给 55 分钟的步骤超时留余量(.github/workflows/healer-gitee.yml:22-23)

另外 .github/ 下还有 ISSUE_TEMPLATE/(bug_report、feature_request、school_adaptation 三个表单)和 PULL_REQUEST_TEMPLATE.md,供提 issue/PR 时使用。

常用 ./gradlew 命令

# 组装 debug APK(三个 ABI 各出一个,见 splits 配置)
./gradlew assembleDebug

# 组装 release APK(走 R8 shrinking,debug keystore 签名)
./gradlew assembleRelease

# 只要某个 ABI,AGP 会生成按变体+ABI 拆分的任务
./gradlew assembleArm64Release

# 单元测试(本仓库的测试主力)
./gradlew testDebugUnitTest

# 全部单元测试变体
./gradlew test

# 连接真机/模拟器跑 androidTest
./gradlew connectedDebugAndroidTest

# 静态检查
./gradlew lint

产物在 app/build/outputs/apk/<variant>/<abi>/ 下。仓库启用了 buildConfig(app/build.gradle.kts:46-49),所以首次构建会生成 BuildConfig 类;单元测试开了 isReturnDefaultValues(app/build.gradle.kts:62-67),android.jar 的方法在 JVM 测试里返回默认值而非抛异常。

相关页面

Clone this wiki locally