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

无需在每个Activity中调用LifecycleObserver,实现Firestore用户在线状态更新

问题描述

我希望根据应用处于前台还是后台,将Firestore中的用户状态更新为在线或离线。目前我使用LifecycleObserver来实现此功能,但问题是必须在每一个Activity中调用它才能生效。请问有没有无需在每个Activity中调用的实现方法?

当前实现的Observer类:

class Observer(private val currentUser: User): LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onEnteredForeground() {
        if (!currentUser.isOnline)
            updateStatus(true)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onEnteredBackground() {
        if (currentUser.isOnline) {
            updateStatus(false)
        }
    }

    private fun updateStatus(status: Boolean) {
        val db = FirebaseFirestore.getInstance()
        db.collection("users").document(currentUser!!.uid)
            .update(
                "isOnline", status
            )
            .addOnSuccessListener {
                Log.d(ContentValues.TAG, "DocumentSnapshot successfully written!")
                return@addOnSuccessListener
            }
            .addOnFailureListener { e ->
                Log.w(ContentValues.TAG, "Error writing document", e)
                return@addOnFailureListener
            }
    }
}

当前调用方式(需在每个Activity中执行):

lifecycle.addObserver(Observer(user))
解决方案

可以借助ProcessLifecycleOwner实现全局的应用前后台监听,无需在每个Activity中注册Observer。这个类能监听整个应用进程的生命周期事件,只要应用从后台回到前台或者进入后台,都会触发对应的回调。

步骤1:修改Observer类

调整原有的Observer,让它适配应用进程的生命周期监听:

class AppLifecycleObserver(private val currentUser: User) : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onAppEnterForeground() {
        if (!currentUser.isOnline) {
            updateUserStatus(true)
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onAppEnterBackground() {
        if (currentUser.isOnline) {
            updateUserStatus(false)
        }
    }

    private fun updateUserStatus(isOnline: Boolean) {
        FirebaseFirestore.getInstance()
            .collection("users")
            .document(currentUser.uid)
            .update("isOnline", isOnline)
            .addOnSuccessListener {
                Log.d("AppLifecycle", "用户状态更新为:${if (isOnline) "在线" else "离线"}")
            }
            .addOnFailureListener { e ->
                Log.w("AppLifecycle", "状态更新失败", e)
            }
    }
}

步骤2:在自定义Application类中注册

创建或修改你的自定义Application类,在onCreate()方法中把Observer注册到ProcessLifecycleOwner:

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        // 替换成你实际获取当前登录用户的逻辑
        val currentUser = getCurrentLoggedInUser()
        currentUser?.let {
            ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver(it))
        }
    }

    // 示例:从Firebase Auth获取当前用户并映射到自定义User实体
    private fun getCurrentLoggedInUser(): User? {
        val firebaseUser = FirebaseAuth.getInstance().currentUser
        return firebaseUser?.let { User(it.uid, it.displayName ?: "", false) }
    }
}

步骤3:配置AndroidManifest.xml

确保在Manifest中指定自定义的Application类:

<application
    android:name=".MyApp"
    <!-- 其他原有配置 -->
    >
    <!-- Activity等组件配置 -->
</application>

注意事项

  • ProcessLifecycleOwner的ON_START会在应用首次启动、从后台回到前台时触发;ON_STOP仅在应用完全进入后台(所有Activity均不可见)时触发,不会因单个Activity切换而触发,完全匹配在线/离线状态的更新需求。
  • 如果用户是在应用启动后才完成登录的,需要在登录成功后补充注册Observer,或者在Observer中处理用户为null的边界情况。

内容的提问来源于stack exchange,提问作者Senith Umesha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:18:22