原生 Kotlin + Jetpack Compose 客户端。设计与价值同源于 iOS 版,功能与交互以 Android 原生为先(不追求与 iOS 一一对应)。 最低 Android 12(API 31),目标 / 编译 API 36。
- JDK 17
- Android SDK(platform
android-36+ 对应 build-tools)
用 Android Studio 打开 apps/android/ 会自动配齐 SDK;或手动安装命令行工具:
# JDK 17(Homebrew 示例)
brew install --cask temurin@17
export JAVA_HOME="$(/usr/libexec/java_home -v 17)"
# Android SDK(命令行工具,无需 Android Studio)
brew install --cask android-commandlinetools
export ANDROID_HOME="$HOME/Library/Android/sdk"
sdkmanager "platforms;android-36" "build-tools;36.0.0" "platform-tools"local.properties 不入库,首次需写入 SDK 路径(Android Studio 会自动生成):
sdk.dir=/path/to/Android/sdk仓库已包含 Gradle Wrapper(./gradlew,Gradle 8.13),直接用即可:
cd apps/android
./gradlew :app:assemblePlayDebug # 官方 Play 版(带 Billing)
./gradlew :app:assembleOssDebug # 开源自编译版(无 Billing,isPro 恒真)
./gradlew :app:testPlayDebugUnitTest # 单测两个产品风味:
| 风味 | applicationId | 说明 |
|---|---|---|
play |
jiamin.chen.orangecloud |
官方版,Play Billing,内置官方 OAuth Client |
oss |
jiamin.chen.orangecloud.oss |
自编译全解锁,无 Billing 依赖,需自填 OAuth Client |
OAUTH_CLIENT_ID 经 Gradle 注入到 BuildConfig:
play风味内置官方 Client ID——OAuth PKCE 下它是公开标识符而非机密,与 iOSOAuthConfig.swift同值。oss风味默认空串。自编译者须在apps/android/local.properties填入自建的 Client ID:并部署自己的回调中转——官方 Client 与OAUTH_CLIENT_ID=你自建的_client_ido-c.do中转不向第三方构建开放,详见根目录CONTRIBUTING.md。
Google 官方 App Architecture,分层无环:
ui/ Compose 屏 + ViewModel(每屏一个 UiState: StateFlow)
data/ Repository(单一可信源)
├─ remote/ CfApiClient(OkHttp) + DTO(@Serializable)
└─ local/ Room(@Entity/@Dao) + DataStore
core/ auth / network / design(晨昏天景)/ di(Hilt)
- Composable 不直接发网络,只读 ViewModel 暴露的
UiState;ViewModel 不持有 OkHttp,只调 Repository。 - Token 只入 Keystore 包裹的加密 DataStore,绝不写明文。
- 数据模型为
@Serializabledata class,@SerialName映射 snake_case。 - 错误统一
ApiError(sealed class),在 ViewModelcatch后赋给UiState.error。 - 用户可见文案一律入
res/values/strings.xml,禁止硬编码字面量。