iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
Software Development

從 Fragment 到 Compose — 老 Android App 重寫的架構取捨系列 第 21 篇

Day 21|離線佇列:Room + WorkManager

  • 分享至 

  • xImage
  •  

動筆前先答(兩題)

1.【模擬面試追問|持久化與離線】 舊 App 送出「交接證明照片」的流程是這樣:

  1. 畫面把照片的 URI 清單放進 Intent,啟動一個負責上傳的 Service(onStartCommand 回傳 START_STICKY)。
  2. Service 用「上傳當下的時間戳記」為每張照片組出檔名,並行上傳到物件儲存。全部完成後,把網址清單放進一個共用的 LiveData。
  3. 畫面觀察那個 LiveData,收到「完成」才呼叫業務 API,把網址清單交給後端。

面試官依序問下面四個情境,每個都要回答三件事:

  • 照片最後在哪裡:只在手機上、已在物件儲存,還是兩邊都沒有?
  • 後端有沒有這筆交接紀錄?
  • 配送員看到什麼?
  1. 按下送出後,使用者馬上切到導航 App 開車。十分鐘後,系統回收了 App 的 process。
  2. 上傳還沒完成,使用者就按返回離開這個畫面,之後上傳成功了。
  3. 三張照片傳成功兩張、失敗一張,配送員按「重試」。
  4. 照片全部上傳成功,但呼叫業務 API 時網路斷了,App 不知道後端到底有沒有收到。配送員再按一次送出。

接著追問:

  • 把上傳改成「Room 存佇列、WorkManager 執行」,上面哪幾個情境的答案會因此變好?哪幾個光換工具還是一樣?還缺什麼?
  • 情境 4 要怎麼做,後端才不會多出一筆重複的交接紀錄?哪些部分 App 自己做得到,哪些一定要後端配合?

我的回答:(待補)

2.【預測再驗證|平台能力】 新版用 WorkManager 執行上傳:

@HiltWorker
class ProofUploadWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted params: WorkerParameters,
    private val uploader: ProofUploader,
) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result =
        when (uploader.uploadNext()) {
            UploadOutcome.Done -> Result.success()
            UploadOutcome.NetworkError -> Result.retry()
            UploadOutcome.Rejected -> Result.failure()
        }
}

fun enqueueProofUpload(context: Context, proofId: String) {
    val request = OneTimeWorkRequestBuilder<ProofUploadWorker>()
        .setConstraints(Constraints(requiredNetworkType = NetworkType.CONNECTED))
        .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
        .build()
    WorkManager.getInstance(context)
        .enqueueUniqueWork("proof-$proofId", ExistingWorkPolicy.KEEP, request)
}

下面每個情境,先寫下你的預測:Worker 會不會執行?什麼時候執行?然後在實機上驗證。可以用 Android Studio 的 App Inspection(Background Task Inspector)或 adb shell dumpsys jobscheduler 觀察。品牌與 Android 版本可能影響結果,請寫下你測試用的機型和 Android 版本。

  1. 開著飛航模式按送出,十分鐘後關掉飛航模式。
  2. 上傳進行中,從「最近使用的應用程式」把 App 滑掉。
  3. 上傳失敗、回傳 retry 之後,到「設定 → 應用程式」按「強制停止」,然後一小時都不打開 App。一小時後打開 App 呢?
  4. 佇列裡還有一筆沒傳完,手機重新開機。開機後不打開 App。
  5. 同一個 proofId 連續呼叫兩次 enqueueProofUpload,執行了幾個 Worker?把 KEEP 換成 REPLACE 再試一次:如果第二次呼叫時第一個正在上傳,它會怎樣?
  6. 一支三分鐘的影片,在訊號很差的地方上傳,超過十分鐘還沒傳完。

最後回答:依你驗證的結果,送出之後畫面要怎麼讓配送員知道「照片還沒傳完」?哪些情況一定要提醒使用者打開 App?

我的回答:(待補)


上一篇
Day 20|CameraX 在 Compose:AndroidView 逃生門原則
下一篇
Day 22|上傳策略:重試、退避與進度
系列文
從 Fragment 到 Compose — 老 Android App 重寫的架構取捨 共 22 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言