服務端數據更新 → 客戶端磁盤緩存失效 → 用戶看到舊圖/舊列表。
| 策略 | 觸發方式 | 實時性 | 實現複雜度 | 適用場景 |
|---|---|---|---|---|
| 用戶操作觸發 | 下拉刷新、進入頁面、點擊重試 | 低 | 極低 | 非強實時、內容型 App |
| 定時輪詢 | AlarmManager / WorkManager 定期請求版本號 | 中 (分鐘級) | 低 | 資訊流、社區 |
| 服務端推送 | FCM / WebSocket / 長連接推送版本變更通知 | 高 (秒級) | 高 | IM、交易、協作 |
| 版本號/ETag 機制 | 請求攜帶本地版本,服務端 304 或返回增量 | 配合上述 | 中 | 所有場景必備 |
// 1. 客戶端請求列表
GET /api/items?version=123&since=20240101
// 2. 服務端響應
// 情況 A: 無變更
HTTP 304 Not Modified
// 情況 B: 有變更
HTTP 200 OK
{
"version": 125,
"deleted_ids": [1001, 1002], // 刪除標識
"updated": [ // 新增/修改
{"id": 1005, "img_url": "https://cdn.com/new.jpg", "v": 5},
...
]
}
// 3. 客戶端處理
// - 遍歷 deleted_ids → 磁盤緩存刪除對應文件、數據庫標記刪除
// - 遍歷 updated → 下載新圖 (Glide/Picasso/Coil 自動處理磁盤緩存 Key)
// - 更新本地 version = 125
https://cdn.com/img.jpg?v=5 或 https://cdn.com/img_.jpg 。// 服務端
class ItemService {
void updateItem(Item item) {
item.setVersion(versionGenerator.next()); // 全局遞增版本號
item.setImgUrl(cdn.upload(newImage)); // 新 URL
db.save(item);
pushService.notifyVersionChange(item.getCategory(), item.getVersion());
}
}
// 客戶端 WorkManager 任務
@HiltWorker
class SyncWorker @AssistedInject constructor(
@Assisted Context context, @Assisted WorkerParameters params,
ApiService api, LocalDb db, PushTokenManager tokenMgr
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val localVersion = db.getVersion("category")
val response = api.getIncremental("category", localVersion)
if (response.is304) return Result.success()
db.applyIncremental(response.body()) // 刪除/更新/插入
return Result.success()
}
}
// FCM 接收推送 → 觸發立即同步
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(message: RemoteMessage) {
if (message.data["type"] == "version_change") {
WorkManager.enqueueUniqueWork("sync_" + message.data["category"],
ExistingWorkPolicy.REPLACE, OneTimeWorkRequestBuilder().build())
}
}
}
deleted_ids,客戶端清理本地緩存與數據庫。