I'm an android beginner, and just looking for some advice with regard to app architecture - specifically relating to using ViewModels. There is no local database, each screen issues a new network request. I'll look to implement room or something similar later.
Main Activity (Movie List)
I have an activity with a 100% size recycle view showing a list of movies, each movie in the recyclerview has a cover image that the user can touch on to be navigated to a player view. The MainActivity (and it's recycler view) is backed by a ViewModel. The Movie object (wrapped by LiveData) has things you'd expect, like title, category, cover image, url to the mp4 file.
private val movies = MutableLiveData<List<Movie>>()
To transition to PlayerActivity, the intent passes the ID of the selected movie as a string extra.
PlayerActivity
When a movie cell in the recycler view of the MainActivity is selected, I create a new intent to transition to the PlayerActivity where the movie is played. There is an imageView with the movie cover image displayed here too. This view is also backed by a ViewModel.
private val selectedMovie = MutableLiveData<Movie>()
In OnCreate() I get the movie_id string extra from the intent, and create the ViewModel (and the ViewModel does a network request using the movie_id). This view also has a button that, when touched, transitions the user to a ScreenshotActivity. The intent to transition to the ScreenshotActivity also passes the movie_id as a string extra.
ScreenshotActivity
Has a recyclerview of screenshots for the movie displayed, and when touched, a network request is sent back to the server to update the cover image of the movie with one of those screenshots. This activity takes the movie_id extra from the PlayerActivity intent to setup the view.
Questions
It's obviously pretty wasteful to do a network request each time, and I understand I should probably use something like room to cache this information locally.
Well it just depends on the size of your network requests. Are they several megabytes? Then yes, I would cache some of the images of the movie locally.
In the absense of a local database, is there a better way to do what I'm doing above with ViewModels? Perhaps a single viewmodel that can be accessed by all of the 3 activities above?
Well, I think that your current approach is not that bad at all, I think we should take a look at the API. In your MovieList
your get all data of the movies right? I think at that moment you should minify the data sent by the API. Then when selecting only one movie, download the content such as screenshots and cache it locally. If you can't edit the API, then yes, I would suggest you to download all the content you need and reuse that as much as possible.
Since your data is already in private val movies = MutableLiveData<List<Movie>>()
, why wouldn't you just pass the selected Movie
to the PlayerActivity
?
Also note that I would not recommend you to use the same ViewModel
for several Activities. Each Activity
depends on it's own.
In doing so, changes could be made directly to the movie object and syncd across all views? Any good examples on how to do this?
Well the app Telegram has some nice ObserverPattern
, I use it a lot in my apps. See this class: NotificationCenter.java. This allows an Activity
to subscribe to events. If another method calls an event
all subscribers gets triggered. This can help you to 'notify' activities to do some work. You can browse the repository to see how you can use it.
Basically, when you want to listen for events
in your Activity
, you need to implement NotificationCenter.NotificationCenterDelegate
. Then override didReceivedNotification(int id, Object... args)
, and (un) subscribe for events
like this:
NotificationCenter.getInstance().addObserver(this, NotificationCenter.scheduleReload);
Then you can notify the subscribed Activities
anywhere by calling:
NotificationCenter.getInstance().postNotificationName(NotificationCenter.scheduleReload);