Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it okay for a ViewModel class implementing LifecycleObserver?

Reading the ViewModel overview, I wonder if it is okay for a ViewModel to simultaneously become a LifecycleObserver too? My point doing that is to disconnect the Firebase listener when user's not interacting with the UI and reconnect it again when the user's interacting with the UI. As far as I have done and know, it works perfectly. But, I'm afraid if it's bad to do so (memory leaks whatsoever). And if so, is there an alternative to that?

class UserProfileViewModel : ViewModel(), LifecycleObserver {
    companion object {
        private const val TAG = "ProfileViewModel"
    }

    private lateinit var mUserProfile: MutableLiveData<DocumentSnapshot>
    private var mRegistration: ListenerRegistration? = null

    override fun onCleared() {
        Log.d(TAG, "onCleared")
        disconnectListener()
    }

    fun getUserProfile(): LiveData<DocumentSnapshot> {
        if (!::mUserProfile.isInitialized) {
            mUserProfile = MutableLiveData()
        }
        return mUserProfile
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun connectListener() {
        Log.d(TAG, "connectListener")
        val user = FirebaseAuth.getInstance().currentUser
        if (user == null) {
            Log.w(TAG, "User not signed in.")
            return
        }
        val firestore = FirebaseFirestore.getInstance()
        val docRef = firestore.collection(UsersContract.COLLECTION_NAME).document(user.uid)
        mRegistration = docRef.addSnapshotListener { snapshot, exception ->
            if (exception != null) {
                Log.w(TAG, "Failed to fetch user data", exception)
                return@addSnapshotListener
            }
            if (snapshot != null && snapshot.exists()) {
                mUserProfile.value = snapshot
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun disconnectListener() {
        Log.d(TAG, "disconnectListener")
        mRegistration?.remove()
        mRegistration = null
    }
}
like image 211
Wei Avatar asked Dec 16 '18 17:12

Wei


1 Answers

If you are not concerned about having the listeners scoped to resume/pause. You can achieve this with a custom live data. You can have a custom livedata like UserProfileLiveData which extends livedata.

Refer to Extend Live Data - https://developer.android.com/topic/libraries/architecture/livedata#extend_livedata

like image 194
Karthi Keyan Avatar answered Sep 28 '22 01:09

Karthi Keyan