Now in getNetworkInformation() you are:
- Create a new
LiveData - Updating
LiveData with setValue
Instead, you should have one LiveData for the APIClient created as a member variable, and then in getNetworkInformation () just update that LiveData member.
In general, your APIClient is a data source. For data sources, you can contain member elements of a LiveData object that are updated when data changes. You can provide recipients with those LiveData objects to make them available in ViewModels, and ultimately listen to them in your actions / snippets. This is similar to how you can take another data source, such as Room, and listen to the LiveData returned by Room.
So, the code in this case will look like this:
@Singleton public class APIClient { private final MutableLiveData<Resource<NetworkInformation>> mNetworkData = new MutableLiveData<>();
Then in your ViewModel ...
// I don't think this should be a Singleton; ViewModelProviders will keep more than one from being instantiate for the same Activity/Fragment lifecycle public class SplashScreenViewModel extends AndroidViewModel { private LiveData<Resource<NetworkInformation>> networkInformationLiveData; @Inject SplashScreenViewModel(@NonNull APIClient apiClient, @NonNull Application application) { super(application); this.apiClient = apiClient; // Initializing the observable with empty data networkInfoObservable = apiClient.getNetworkData() } public LiveData<Resource<NetworkInformation>> getNetworkInfoObservable() { return networkInformationLiveData; } }
Your activity may be the same as you originally encoded it; it will just receive and see LiveData from the ViewModel.
So what is Transformations.switchMap for?
switchMap is not required here because you do not need to change the underlying instance of LiveData in APIClient . This is because in fact there is only one piece of changing data. Say, instead, your APIClient for some reason needed 4 different LiveData, and you wanted to change which LiveData you watched:
public class APIClient { private MutableLiveData<Resource<NetworkInformation>> mNetData1, mNetData2, mNetData3, mNetData4; ... }
Then let's say that your fetchNetworkInformation will reference different LiveData to observe depending on the situation. It might look like this:
public LiveData<Resource<NetworkInformation>> getNetworkInformation(int keyRepresentingWhichLiveDataToObserve) { LiveData<Resource<NetworkInformation>> currentLiveData = null; switch (keyRepresentingWhichLiveDataToObserve) { case 1: currentLiveData = mNetData1; break; case 2: currentLiveData = mNetData2; break;
In this case, the actual LiveData coming from getNetworkInformation is a change, and you also use some kind of parameter to determine which LiveData you want. In this case, you should use switchMap because you want to make sure that the watch statement that you called in your Activity / Fragment is watching the LiveData returned from your APIClient , even if you change the underlying instance of LiveData. And you do not want to call observation again.
Now this is a slightly abstract example, but basically this is what your Room Dao calls do - if you have a Dao that queries your RoomDatabase based on an identifier and returns a LiveData , it will return another instance of LiveData based on the identifier.