Feb 24 | 3:55 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Feb 24 | 4:00 PM |
Andy | has entered the room |
Mark M. |
hello, Andy!
|
Mark M. |
how can I help you today?
|
Andy |
Hi Mark!
|
Andy |
I have questions about the Repository pattern after reading your section on it in Android Architecture Components.
|
Mark M. |
OK
|
Andy |
I have a question about the best practice in android apps when it comes to using cached or network data. Perhaps it depends on the nature of the data involved. Let’s say I want to display a list of currently open restaurants. If I resume the app to see the list, should the user expect to see cached or networked data? Your example in the book only uses the cache unless it's empty
|
Mark M. |
what do you mean by "resume the app"? do you mean the user had been in the app, left some time ago, and then later returns to the still-running app?
|
Andy |
data retrieval call is made in onResume()
|
Mark M. |
that did not really answer my question, since onResume() occurs at several different points for different reasons
|
Feb 24 | 4:05 PM |
Andy |
If the user presses the home button to background the application. Then presses the launcher to resume, thereby invoking the onResume() method
|
Mark M. |
IMHO, that is based mostly on time
|
Mark M. |
your app would not only keep track of the currently-open restaurants, but also when you fetched that data
|
Mark M. |
so, if the user is in the app, presses HOME, and immediately returns to the app, you realize that you were only gone for a second and the cached data is fresh enough
|
Mark M. |
if, instead, the user is in the app, presses HOME, leaves for 15 minutes, then returns to the app, your app would realize that the cached data is perhaps stale, still shows it (along with a progress indicator), and calls the Web service to refresh the data
|
Mark M. |
this is in addition to any manual refresh options that you might have (refresh toolbar button, pull-to-refresh, etc.)
|
Feb 24 | 4:10 PM |
Andy |
OK, I have some ideas how I could implement that. I could either compare timestamps of a "getWords()" call or use a background service to evict the cache every so often
|
Feb 24 | 4:15 PM |
Andy |
In android apps when is a progressbar appropriate if there is cached data? Should you show the cached data instead of the progress bar? In other words, should the progress bar only be shown prior to the asynchronous request if the cache is empty?
|
Mark M. |
as usual, the answer is "it depends"
|
Feb 24 | 4:20 PM |
Mark M. |
in your case, I would show the progress bar on first start (if you will not be showing the cached data because it is far too stale) or on a manual refresh
|
Mark M. |
the first-start scenario would also cover the "we have no cached data" case
|
Mark M. |
this presumes that the progress indicator does not interfere with the use of the UI, the way that ProgressDialog did
|
Andy |
yeah, I have used and worked on a couple different apps and did not notice a consistent pattern. I don't recall material design dictating this
|
Feb 24 | 4:30 PM |
Andy |
View paste
|
Mark M. |
I am uncertain what needs to be fixed -- the restaurants near a location do not depend on what screen your app is one
|
Mark M. |
er, what screen your app is on
|
Feb 24 | 4:35 PM |
Mark M. |
you might want to use LruCache or some other LRU-style cache, though, rather than HashMap, to avoid running out of heap space
|
Andy |
thanks, I'll consider it
|
Andy |
The issue is that since my cache isn't empty, I'm only making the Retrofit call once. I suppose a solution would be what you said about evicting that cache entry after a time.
|
Mark M. |
you should be making the Retrofit call once per Location, and for a refresh you can have getRestaurants() take a Boolean flag, as you suggested previously
|
Feb 24 | 4:40 PM |
Andy |
cool. I've encountered this issue before and am curious about the solution but also whether my idea is properly architected. Discussing to clarify or confirm
|
Mark M. |
I cannot really say whether your idea is properly architected -- that requires more knowledge about your app and its use cases than I posess
|
Mark M. |
other than the runaway-cache-size problem, though, what you describe seems reasonable
|
Andy |
what can i answer about the app?
|
Feb 24 | 4:45 PM |
Mark M. |
that is really beyond the scope of these chats
|
Mark M. |
if the app is open source, and you want me to code-review parts of it and discuss architecture along the way, that is possible, and I have done that here before, though not often
|
Andy |
ok. If an API supports paging how ought the repository cache it? In this example, I have a cache of Location to List<Restaurant>. Am I supposed to cache per page
|
Mark M. |
I guess so -- I have not had to deal with that, so I have not given that scenario much thought
|
Feb 24 | 4:50 PM |
Andy |
many apis have a query param that takes in the offset and a number of results to reduce response bandwidth. So typically you wouldn't be making a call to the repository to return the entire list.
|
Mark M. |
the Architecture Components have a Paging library that hides a lot of those details
|
Mark M. |
however, I have not used that yet with a Web service where I might need caching
|
Andy |
hmm I'll check it out. I have seen some code where they do this in the repository layer but didn't understand it
|
Mark M. |
if you use the Paging library, your calls to the repository would appear to return the entire list, with the network I/O for each page happening asynchronously
|
Mark M. |
I have some coverage of it for Room (which supports Paging directly) in *Android's Architecture Components*
|
Andy |
ok, I'll check it out
|
Andy |
good afternoon
|
Feb 24 | 4:55 PM |
Mark M. |
you too!
|
Feb 24 | 5:00 PM |
Mark M. |
that's a wrap for today's chat
|
Mark M. |
the transcript will be posted to https://commonsware.com/office-hours/ shortly
|
Mark M. |
the next chat is Tuesday at 7:30pm US Eastern
|
Andy | has left the room |
Mark M. | turned off guest access |