Android模拟经营游戏后台运行:应用关闭时离线获收益的实现咨询
Android模拟经营游戏离线持续收益实现方案
核心思路
别想着让应用在后台一直跑——Android系统会限制后台进程,还费电。靠谱的做法是基于时间差计算收益:记录玩家上次退出/切后台的时间,下次打开应用时,用当前时间减去上次时间,算出离线时长,再按游戏内的收益速率结算这段时间的总收益。
具体实现步骤
1. 存储关键时间点
每次玩家退出应用(包括按Home键、主动关闭、被系统杀死),把当前时间戳存到本地(SharedPreferences或Room数据库都可以)。
示例代码(Kotlin + SharedPreferences):
// 退出时保存时间戳 val gamePrefs = getSharedPreferences("GameData", Context.MODE_PRIVATE) gamePrefs.edit() .putLong("lastActiveTime", System.currentTimeMillis()) .apply()
2. 启动应用时结算收益
玩家打开应用或从后台回到前台时,读取上次存储的时间,计算离线时长,再算出收益:
// 获取本地存储的时间和当前时间 val gamePrefs = getSharedPreferences("GameData", Context.MODE_PRIVATE) val lastActive = gamePrefs.getLong("lastActiveTime", System.currentTimeMillis()) val currentTime = System.currentTimeMillis() // 计算离线时长(转成秒,根据游戏需求调整单位) val offlineSeconds = (currentTime - lastActive) / 1000 // 按收益速率计算总收益(比如每秒赚3金币) val earnPerSecond = 3L val totalOfflineEarn = offlineSeconds * earnPerSecond // 更新玩家金币并刷新界面 val currentGold = gamePrefs.getLong("playerGold", 0L) gamePrefs.edit() .putLong("playerGold", currentGold + totalOfflineEarn) .putLong("lastActiveTime", currentTime) // 更新时间,避免重复计算 .apply()
3. 规避系统时间篡改问题
如果玩家手动修改系统时间,会导致时间差计算异常。可以加个服务器时间校验:
- 应用启动时请求服务器的当前时间
- 对比服务器时间和本地时间,若差值过大(比如超过10分钟),就用服务器时间来计算离线时长
伪代码示例:
// 自行实现网络请求获取服务器时间 val serverCurrentTime = fetchServerCurrentTime() val timeOffset = Math.abs(serverCurrentTime - System.currentTimeMillis()) val validLastActive = if (timeOffset > 10 * 60 * 1000) { // 本地时间被篡改,用服务器时间作为基准 serverCurrentTime - offlineSeconds * 1000 } else { lastActive } // 用validLastActive重新计算收益
4. 可选:后台通知提示(非必须)
如果想给玩家发离线收益提醒,可以用WorkManager做定时任务,比如每小时触发一次,计算当前应得收益并推送通知,但别太频繁,避免耗电:
// 创建定时任务(每1小时执行一次) val workRequest = PeriodicWorkRequestBuilder<OfflineEarnNotificationWorker>(1, TimeUnit.HOURS) .build() WorkManager.getInstance(context).enqueue(workRequest) // Worker实现类 class OfflineEarnNotificationWorker(context: Context, params: WorkerParameters) : Worker(context, params) { override fun doWork(): Result { val gamePrefs = applicationContext.getSharedPreferences("GameData", Context.MODE_PRIVATE) val lastActive = gamePrefs.getLong("lastActiveTime", System.currentTimeMillis()) val currentTime = System.currentTimeMillis() val offlineSeconds = (currentTime - lastActive) / 1000 val earn = offlineSeconds * 3L // 发送通知 val notification = NotificationCompat.Builder(applicationContext, "GameChannel") .setSmallIcon(R.drawable.ic_coin) .setContentTitle("离线收益到账!") .setContentText("你离线期间赚了${earn}金币") .setPriority(NotificationCompat.PRIORITY_LOW) .build() NotificationManagerCompat.from(applicationContext).notify(1001, notification) return Result.success() } }
注意事项
- 绝对不要用前台Service一直挂后台,Android 8.0+对后台进程限制极严,很容易被杀死,还会触发用户的耗电投诉。
- 时间差计算是模拟经营游戏离线收益的标准方案,稳定又省资源,几乎所有同类游戏都是这么做的。
内容的提问来源于stack exchange,提问作者Leonardo Biagi
相关产品推荐
相关产品推荐

