I have three components whose data I have to synchronise.
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
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
.
Activity - Here the data which is received is modified.
What would be the best way to sync this modification across all the three components?
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'.