实现自动更新的基本思路
在 Android 应用中实现自动更新功能,通常需要结合远程服务器版本检测、下载更新包和安装三个核心步骤。对于文字游戏这类轻量级应用,可以优先考虑简化流程。
使用 Firebase App Distribution
Firebase 提供了轻量级的测试版分发和更新方案,适合中小型开发团队:
在
build.gradle
中添加依赖:implementation 'com.google.firebase:firebase-appdistribution-gradle:4.0.0'
配置应用级
build.gradle
:firebaseAppDistribution { appId = "your-firebase-app-id" serviceCredentialsFile = "path/to/credentials.json" releaseNotesFile = "path/to/releasenotes.txt" }
检查更新代码:
FirebaseAppDistribution.getInstance().checkForNewRelease().addOnCompleteListener { task -> if (task.isSuccessful && task.result != null) { // 显示更新对话框 } }
通过 API 实现自定义更新
如需更灵活控制,可自行搭建版本管理系统:
创建版本检测接口:
interface UpdateService { @GET("api/version") suspend fun checkVersion(): Response<VersionInfo> }
实现版本比较逻辑:
fun needsUpdate(current: String, latest: String): Boolean { return current.split(".").map { it.toInt() } < latest.split(".").map { it.toInt() } }
下载 APK 文件:
val downloadManager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager val request = DownloadManager.Request(Uri.parse(url)) .setDestinationInExternalPublicDir(DIRECTORY_DOWNLOADS, "update.apk") downloadManager.enqueue(request)
处理 APK 安装
Android 8.0 以上需要特殊权限处理:
在 AndroidManifest.xml 中添加权限:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
注册下载完成广播接收器:
val filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE) registerReceiver(downloadReceiver, filter)
安装 APK 的代码:
val intent = Intent(Intent.ACTION_VIEW).apply { setDataAndType(uri, "application/vnd.android.package-archive") flags = Intent.FLAG_ACTIVITY_NEW_TASK addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } startActivity(intent)
增量更新优化
为减少流量消耗,可考虑实现增量更新:
使用 bsdiff 生成差异包:
bsdiff old.apk new.apk patch.diff
在应用中集成 bspatch:
external fun applyPatch(oldPath: String, newPath: String, patchPath: String): Int
加载本地库:
System.loadLibrary("bspatch")
用户界面设计建议
更新流程应提供友好的用户交互:
显示更新进度条:
val progressBar = findViewById<ProgressBar>(R.id.progress_bar) downloadManager.registerListener { bytesDownloaded, totalBytes -> progressBar.progress = (bytesDownloaded * 100 / totalBytes).toInt() }
实现后台静默下载(需用户授权):
val notification = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("游戏更新中") .setSmallIcon(R.drawable.ic_download) .build() startForeground(NOTIFICATION_ID, notification)
版本回滚机制
为应对更新失败情况,建议保留旧版本:
实现版本回滚检测:
fun shouldRollback(version: String): Boolean { return version.contains("beta") && hasCriticalBugReported() }
备份当前 APK:
val currentApk = File(packageManager.getApplicationInfo(packageName, 0).sourceDir) val backupFile = File(getExternalFilesDir(null), "backup.apk") currentApk.copyTo(backupFile, overwrite = true)
注意事项
- 需要处理 Android 11 的存储权限变更
- 考虑不同厂商 ROM 的安装限制
- 更新服务器应具备防篡改机制
- 建议支持断点续传功能
- 遵守 Google Play 的更新政策(如果上架)