0

I'm using databinding, the Jetpack Navigation Component (in which one activity hosts several fragments) and a shared ViewModel with activityViewModels() in the fragments. The Room database is initialized (and some resource expensive queries) when a ViewModel function is called from the StartFragment (hosted by the MainActivity). The host activity is created twice (and destroyed once), causing the fragment to do the same and duplicate Room queries.

ViewModel varialble in the Fragment:

private val viewModel: WorkoutListViewModel by activityViewModels()

ViewModel function:

    if (applicationStarted) {
        roomDb = WorkoutsRoomDatabase.getInstance(application)
        repository = WorkoutsRepository(roomDb)
        collectAllWorkouts()  // Expensive database query
        insertWorkoutGroup(WorkoutGroup(FIRST_TAB_TITLE), null)
    }

I know the activity, fragment creation and Room queries happen twice because I used logs to test it. I suspect the cause is related to databinding, the navigation component, or the way the shared ViewModel with activityViewModels(). Even though there's better ways to initialize the database and start queries, I appreciate an input on this too but my question is specifically about the host activity being created twice.

edit: The activity it created -> destroyed -> created

The bundle is null at first and the second time it is:

Bundle[{android:viewHierarchyState=Bundle[{android:views={16908290=android.view.AbsSavedState$1@cd936b5, 2131230775=android.view.AbsSavedState$1@cd936b5, 2131230790=android.view.AbsSavedState$1@cd936b5, 2131231216=android.view.AbsSavedState$1@cd936b5}}], androidx.lifecycle.BundlableSavedStateRegistry.key=Bundle[{android:support:lifecycle=Bundle[{}], androidx.lifecycle.internal.SavedStateHandlesProvider=Bundle[{}]}], android:lastAutofillId=1073741824, android:fragments=android.app.FragmentManagerState@c25a14a}]

madbeans
  • 99
  • 1
  • 14
  • 1
    Not the answer you are searching for, but the ViewModel should work in such a way that the activity being created twice does not fetch the workouts again. That way, the VM serves its' purpose holding state. The views can be recreated at any point by the OS, because of rotation, split window or changing dark mode settings. Not refetching workouts should be the first problem to solve, the recreating activity second. A first proposal: Could the database be fetched on init of the VM? – Michiel Jul 17 '22 at 20:24
  • 1
    Can you reproduce the problem that the `Activity` is created twice? Is `onDestroy()` called on the first `Activity` AFTER or BEFORE the second instance is created? When the second instance is created is the `Bundle` passed to `onCreate()` = `null`? – David Wasser Oct 06 '22 at 11:19
  • @DavidWasser created, destroyed, created. The bundle is null the first time and has a value the second time, I don't know what that means but I think you're on to something. I updated my answer with the value of the bundle. – madbeans Oct 11 '22 at 00:39
  • Generally, the sequence `onCreate()`, `onDestroy()`, `onCreate()` (where the second `onCreate()` has a non-null `Bundle`) is an orientation or configuration change. Do you see this happening every time? or just some times? Also, are you sure you aren't restarting the `Activity` by calling `startActivity()` with an `Intent`? – David Wasser Oct 11 '22 at 07:39

0 Answers0