Answers to your questions:
- I recommend having a separate API layer to handle your background tasks. I recommend exposing each API call through RxJava, and ensuring that only the Presenter has access to the API. RxJava would do the heavy lifting of allowing you to combine the requests together in your application layer / presenters.
- Square recently did a talk on this and there solution. You can find a link to it here. Bottom line, it's not an easy problem to solve. If you are looking for a simple solution, my team and I created a concept called preferences. Each Preference represents a single piece of data that's stored in memory or persisted to disk using shared preferences. Here is an example of a library we used to do this. This library uses RxJava1, and we upgraded it privately to RxJava2, but you can get the point. Each piece of data is a dependency that we use Dependency Injection to pass between presenters / screens to get it where we need it.
- Can't answer this one. My team doesn't use Interactors. We use a separated API layer as I described in #1, and RxJava allows all of those calls to be extremely flexible and re-usable. You will drive yourself crazy if you are dogmatic about everything you read in blogs. A lot of the things I've read in blogs just aren't practical in principal. I recommend using common sense, and finding what works for your team.
Here is a short sell on MVI (Model View Intent). I highly recommend it:
My team recently tried adopting MVP about a year ago. It didn't take long for us to realize some shortcomings, and have issues similar to you. After some searching we moved to Model-View-Intent (MVI). It's very similar to MVP, but with a few key differences that make the code far more manageable and easier to standardize the code between developers, making it easier jump into other peoples code.
A few key differences: The View doesn't talk to the Presenter, instead the View emits events that the Presenter subscribes to, called Intents. The Presenter also talks to the View via strong View Model. If you draw it out, it ends up functioning very similarly to MVVM. You end up with a flow that looks like this:
- The Presenter subscribes to the View events / intents.
- The View emits events.
- The Presenter receives the events, reacts, and updates the model.
- The Model being updated triggers an update to the View
- Round and round it goes. (It ends up being a very circular loop of events if you draw it out)
Hannes Dorfmann has a few blog posts on MVI that I recommend. He provides some pretty complex examples. My team uses Kotlin, and that helps with this a LOT. We don't follow everything Hannes does, but we learned a lot from his blog posts / examples, and distilled into something that works REALLY well for our team.
- http://hannesdorfmann.com/android/model-view-intent
- http://hannesdorfmann.com/android/mosby3-mvi-1
- http://hannesdorfmann.com/android/mosby3-mvi-2
- http://hannesdorfmann.com/android/mosby3-mvi-3
- http://hannesdorfmann.com/android/mosby3-mvi-4
- http://hannesdorfmann.com/android/mosby3-mvi-5
- http://hannesdorfmann.com/android/mosby3-mvi-6