2

enter image description here

Here's what I am trying to do.

I have 2 fragments hosted in MainActivity.

Fragment 1 has just a couple of widgets to update. Fragment 2 has a recycler view to display the list of items.

I first get an instance of the data class and call its fetchData method.

The fetchData() method communicates with the local database to first see if my data is already stored in my local database.

If it is stored, then it simply returns that data and the recycler view in fragment 2 simply display that data.

But the problem arises when I have to fetch fresh data from the internet if data in my local database is not already present which is an asynchronous call. (The library I am using to call web API is Volly)

Now I am confused how to tell Fragment 1 and Fragment 2 to use the updated data once the database is updated?

HQuser
  • 640
  • 10
  • 26
  • 1
    pls, explain your problem in brief. your requirement is like if not update from internet then call from local otherwise call from Internet.right..? – Ketan Patel Mar 20 '18 at 06:27
  • the problem is, if my database is not updated then update my database from internet and then display that data to my fragments. – HQuser Mar 20 '18 at 06:29
  • 1
    ok then you want to first data store in database after that display from database, not from Internet directly..? – Ketan Patel Mar 20 '18 at 06:31
  • the idea is to first check my database if my data is already present and up to date in order to save unnecessary calls to web API. If my data is not saved in database or is not up-to-date then simply fetch data from internet, update my database and then display the data from database to all the fragments. – HQuser Mar 20 '18 at 06:33
  • 1
    OK then you should go with timestamps. – Ketan Patel Mar 20 '18 at 06:35
  • can you explain more about timestamps? – HQuser Mar 20 '18 at 06:36
  • 1
    when update data from internet then your time and internet data time not matched so u should update – Ketan Patel Mar 20 '18 at 06:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/167139/discussion-between-hquser-and-ketan-patel). – HQuser Mar 20 '18 at 06:37
  • first you addd parameter in server of time field also in your database – Ketan Patel Mar 20 '18 at 06:37
  • 1
    It seems that the problem you face is larger than you feel it. In general, you need to organize the code to handle the logic you described. It is not about specific method or field. It is about the structure of an app. I really recommend you this article: https://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/ It might look little bit overwhelming. In that case, check the links in that article to get a better understanding. – Artem Sborets Mar 20 '18 at 06:54
  • 1
    refer https://stackoverflow.com/questions/19662851/how-to-call-method-in-activity-form-non-activity-class – sasikumar Mar 20 '18 at 08:47
  • @sasikumar thank you for a breakthrough but how do I cast context to specific Fragment as kotlin is giving me an error when I try to check if (context is Fragment1) it says incompetible types context and Fragment1 – HQuser Mar 20 '18 at 09:41
  • 1
    use another interface from activity to fragment. – sasikumar Mar 20 '18 at 09:58

1 Answers1

2

A convenient way to connect activity and fragments inside it is provided by architecture components.

  1. Create a ViewModel, that will host your data class instance. https://developer.android.com/topic/libraries/architecture/viewmodel.html#implement

  2. Get view model reference in both your fragments.

    final MyModel viewModel = ViewModelProviders.of(getActivity()).get(MyModel.class);
    
  3. Make your ViewModel expose results of your data class as LiveData. https://developer.android.com/topic/libraries/architecture/livedata.html

    private MutableLiveData<String> mCurrentData;
    
    public MutableLiveData<String> getCurrentData() {
        if (mCurrentName == null) {
            mCurrentData = new MutableLiveData<String>();
        }
        return mCurrentData;
    }
    
    public void updateData() {
        getCurrentData().setValue(myDataClass.getNewData());
    }
    
  4. Subscribe to the provided live data in both your fragment your.

    // Get the ViewModel.
    mModel = ViewModelProviders.of(getActivity()).get(MyModel.class);
    
    // Create the observer which updates the UI.
    final Observer<String> myObserver = new Observer<String>() {
        @Override
        public void onChanged(@Nullable final String newData) {
            // do something with the new data
        }
    };
    
    // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
    mModel.getCurrentData().observe(this, myObserver);
    

Using this approach both your fragments will get the same updates in your myObserver instances in both fragments from the ViewModel.

Here you can find a more detailed guide.

TpoM6oH
  • 8,385
  • 3
  • 40
  • 72