You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现MySQL到Android Room的数据自动同步

实现Web到Android Room的库存自动同步(基于Retrofit2)

以下是针对你的需求的几种实用实现方案,均基于Retrofit2展开,适合Android新手快速落地:

方案1:定时轮询(最易上手)

通过定期发起Retrofit请求拉取后端更新的库存数据,同步到Room,是新手最容易实现的方案。

步骤:

  1. 后端新增增量查询接口
    接口需要支持传入上次同步的时间戳,返回该时间之后更新的库存记录(依赖MySQL表中的update_time字段,每次数据修改自动更新该字段)。
    Retrofit接口定义示例:

    interface InventoryApi {
        // 传入上次同步时间,返回更新后的库存列表
        @GET("api/inventory/updated")
        suspend fun getUpdatedInventories(@Query("last_sync") lastSyncTime: Long): Response<List<Inventory>>
    }
    
  2. 用WorkManager实现可靠定时任务
    Android后台限制较多,WorkManager是官方推荐的定时任务方案,能适配不同版本的后台规则:

    class InventorySyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
        override suspend fun doWork(): Result {
            return try {
                // 1. 获取Retrofit实例
                val api = RetrofitClient.getInstance().create(InventoryApi::class.java)
                // 2. 从SharedPreferences取上次同步时间
                val lastSyncTime = getSharedPreferences("sync_prefs", Context.MODE_PRIVATE)
                    .getLong("last_sync_time", 0)
                // 3. 请求增量数据
                val response = api.getUpdatedInventories(lastSyncTime)
                if (response.isSuccessful) {
                    response.body()?.let { updatedList ->
                        // 4. 同步到Room
                        val dao = AppDatabase.getInstance(applicationContext).inventoryDao()
                        dao.upsertAll(updatedList)
                        // 5. 保存本次同步时间
                        getSharedPreferences("sync_prefs", Context.MODE_PRIVATE)
                            .edit()
                            .putLong("last_sync_time", System.currentTimeMillis())
                            .apply()
                    }
                    Result.success()
                } else {
                    // 请求失败,稍后重试
                    Result.retry()
                }
            } catch (e: Exception) {
                // 捕获网络异常等,避免任务崩溃
                Result.failure()
            }
        }
    }
    
  3. 启动定时任务
    在应用启动时(比如Application类或MainActivity的onCreate)初始化定时同步:

    val syncRequest = PeriodicWorkRequestBuilder<InventorySyncWorker>(15, TimeUnit.MINUTES)
        .setConstraints(Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED) // 仅在联网时同步
            .build())
        .build()
    
    WorkManager.getInstance(this).enqueueUniquePeriodicWork(
        "InventorySync",
        ExistingPeriodicWorkPolicy.REPLACE,
        syncRequest
    )
    
  4. Room中定义Upsert方法
    Room的@Upsert注解会自动判断数据是新增还是更新,无需手动区分:

    @Dao
    interface InventoryDao {
        @Upsert
        suspend fun upsertAll(inventories: List<Inventory>)
    }
    

方案2:Webhook触发的即时同步(更高效)

如果需要实时性更高的同步,可以让Web端在修改MySQL后,通过推送通知触发Android端立即拉取数据,再用Retrofit完成同步。

步骤:

  1. Web端触发通知
    Web端修改库存后,调用第三方推送服务(如FCM)给Android设备发送通知,告知有数据更新。

  2. Android端监听推送并同步
    实现Firebase消息监听服务,收到通知后立即发起Retrofit请求同步数据:

    class InventoryMessagingService : FirebaseMessagingService() {
        override fun onMessageReceived(remoteMessage: RemoteMessage) {
            super.onMessageReceived(remoteMessage)
            // 判断是否是库存更新通知
            if (remoteMessage.data["event"] == "inventory_change") {
                // 在IO线程执行同步
                CoroutineScope(Dispatchers.IO).launch {
                    syncInventory()
                }
            }
        }
    
        private suspend fun syncInventory() {
            // 复用方案1中的同步逻辑
            val api = RetrofitClient.getInstance().create(InventoryApi::class.java)
            val lastSyncTime = getSharedPreferences("sync_prefs", Context.MODE_PRIVATE)
                .getLong("last_sync_time", 0)
            val response = api.getUpdatedInventories(lastSyncTime)
            if (response.isSuccessful) {
                response.body()?.let {
                    val dao = AppDatabase.getInstance(applicationContext).inventoryDao()
                    dao.upsertAll(it)
                    getSharedPreferences("sync_prefs", Context.MODE_PRIVATE)
                        .edit()
                        .putLong("last_sync_time", System.currentTimeMillis())
                        .apply()
                }
            }
        }
    }
    
  3. 权限配置
    Android 13+需要申请POST_NOTIFICATIONS权限,才能接收推送通知。

关键优化点

  • 增量同步:始终只拉取上次同步后更新的数据,避免全量传输浪费带宽和时间
  • 数据一致性:给MySQL库存表添加version字段,更新时校验版本号,防止并发修改导致的数据冲突
  • 异常处理:Retrofit请求必须包裹try-catch,处理网络异常、接口错误等情况
  • 后台适配:避免用Timer或Handler实现定时任务,WorkManager能自动适配Android后台限制

内容的提问来源于stack exchange,提问作者Emiliano Cahayon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:10:06