Search code examples
androidsqliteandroid-contentprovider

Synchronise data across multiple activities/fragments


I have three components whose data I have to synchronise.

  1. Activity - This activity get data from Content Provider and has a ViewPager. It passes this data (Fragment.getInstance(data...)) to the second component which is a Fragment

  2. Fragment - This fragment has a RecyclerView and onClick() of a particular item, data is passed through intent to the third component which is an Activity.

  3. Activity - Here the data which is received is modified.

What would be the best way to sync this modification across all the three components?


Solution

  • Do not hold references to the same POJOs (Plain old java object) between different activities and fragments. Use shared preferences or a SQL db instead.

    Activities and fragments are supposed to be stateless. So I am going to tell you how to transfer data between activities and fragments rather than how to synchronize data.

    Let's take them case by case:

    • '1 to 2': You probably already have all the fragments in the activity. So just call fragment.sendData(...) to send data to the fragment. Caveat: In case you are using a FragmentStateAdapter you will have to do this (reference):

      if (adapter.getCount() > 0) {
          fragment = (MyFragment) adapter.instantiateItem(
                  null, viewPager.getCurrentItem());
          // A NullPointerException is thrown if the item isn't initialized as yet
          // So be careful.
      }
      
    • '2 to 1': Create a fragment callback interface (say FragmentCallback) that the activity1 must implement i.e. override Fragment.onAttach(Activity activty), check if activity instanceof FragmentCallback and throw an exception if it isn't. (This is automatically generated by android studio when you create a new fragment)

    • '1 to 3': Start the activity by passing an Intent with the data.

    • '2 to 3': Start the activity by passing an Intent with the data. In case you need some data from activity1, don't use this method. Use '2 to 1' followed by '1 to 3' instead.

    • '3 to 1': The correct way to do it is to start a new activity1 with Intent data or send it to the original activity1 using startActivtyForResult and handle the result in activity1. You can use android:launchMode="singleTop" (ref) if needed. If you have to send it the original activity (in a way that cannot be satisfied by startActivtyForResult), it's definitely a code smell. Use shared preferences or something and check it in Activity1.onResume and/or Activity1.onCreate.

    • '3 to 2': Use '3 to 1', followed by '1 to 2'.