Kotlin中如何在应用终止时更新Firebase数据?
问题描述
我希望在应用终止时更新Firebase中的数据,但尝试onDestroy和onPause方法都没达到预期:
onPause会在应用每次进入后台时执行更新,这不是我想要的;onDestroy方法完全没生效。
附上我的代码:
// This onDestroy didn't work; OnPause triggers every time the application goes to the background override fun onDestroy() { super.onDestroy() Log.d("ClosingService", "Service is destroyed. Updating user data...") Update_User_Data(dataManager.userDataList) } fun Update_User_Data(newDataList : ArrayList<User_Structure>){ val tasks = newDataList.map { i -> val userRef = db.collection("users").document(i.userId) userRef.update(mapOf( "username" to i.username, "favorites" to i.favorites, "parts" to i.parts, "points" to i.points )) } Tasks.whenAllComplete(tasks).addOnCompleteListener { if (it.isSuccessful) { println("All user data updated successfully!") } else { println("Error updating some user data.") } } }
解决方案
1. 为什么onDestroy不生效?
Android系统中onDestroy并不可靠:当系统需要紧急回收内存时,会直接杀死应用进程,不会触发该回调;用户主动划掉应用的部分场景下,也不会走这个方法。
2. 精准监听应用终止:用ProcessLifecycleOwner
通过Jetpack Lifecycle组件的ProcessLifecycleOwner,可以监听应用从前台进入后台且长时间未返回的状态,以此判断应用是否真正终止:
步骤1:引入依赖(未添加的话)
implementation "androidx.lifecycle:lifecycle-process:2.6.2"
步骤2:在Application类注册监听
class MyApp : Application() { override fun onCreate() { super.onCreate() ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver()) } }
步骤3:实现自定义LifecycleObserver
class AppLifecycleObserver : DefaultLifecycleObserver { private var backgroundEnterTime: Long = 0 override fun onPause(owner: LifecycleOwner) { super.onPause(owner) // 记录进入后台的时间 backgroundEnterTime = System.currentTimeMillis() } override fun onStop(owner: LifecycleOwner) { super.onStop(owner) // 延迟2秒判断:如果2秒后应用仍在后台,说明用户没有返回,执行更新 Handler(Looper.getMainLooper()).postDelayed({ val isAppInBackground = !ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) if (isAppInBackground) { Update_User_Data(dataManager.userDataList) Log.d("AppTermination", "应用已终止,执行Firebase数据更新") } }, 2000) } }
3. 优化Firebase更新逻辑
原方法存在日志不规范、未单独处理单条更新失败的问题,优化后:
fun Update_User_Data(newDataList: ArrayList<User_Structure>) { val tasks = newDataList.map { user -> val userRef = db.collection("users").document(user.userId) userRef.update(mapOf( "username" to user.username, "favorites" to user.favorites, "parts" to user.parts, "points" to user.points )).addOnFailureListener { e -> // 单独记录单条更新失败的日志 Log.e("FirebaseUpdate", "更新用户${user.userId}失败: ${e.message}") } } Tasks.whenAllComplete(tasks).addOnCompleteListener { if (it.isSuccessful) { Log.d("FirebaseUpdate", "所有用户数据更新成功") } else { Log.e("FirebaseUpdate", "部分用户数据更新失败") } } }
4. 更可靠的备选方案:WorkManager延迟任务
如果需要系统在应用终止后仍完成更新,可使用WorkManager创建延迟任务:
// 调度更新任务 fun scheduleUserDataUpdate(dataList: ArrayList<User_Structure>) { // 需确保User_Structure实现Parcelable或Serializable val inputData = workDataOf("user_data" to dataList) val updateWork = OneTimeWorkRequestBuilder<UserDataUpdateWorker>() .setInputData(inputData) .setInitialDelay(2, TimeUnit.SECONDS) .build() WorkManager.getInstance(applicationContext).enqueue(updateWork) } // 实现Worker类 class UserDataUpdateWorker(context: Context, params: WorkerParameters) : Worker(context, params) { override fun doWork(): Result { val dataList = inputData.getParcelableArrayList<User_Structure>("user_data") ?: return Result.failure() Update_User_Data(dataList) return Result.success() } }
只需在AppLifecycleObserver的onStop中调用scheduleUserDataUpdate即可。
内容的提问来源于stack exchange,提问作者Umut.jpg
相关产品推荐
相关产品推荐

