May 10 | 8:50 AM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
May 10 | 9:05 AM |
Michaelidle | has entered the room |
Mark M. |
hello, Michaelidle
|
Mark M. |
how can I help you today?
|
May 10 | 9:10 AM |
Michaelidle |
Hey Mark. Two questions for you today. 1. I have a master detail flow in one of my applications. It's currently a list of conversations and then you drill down into the messages in that conversation. When you enter the detail activity, I do an async query for messages. Works great. On rotation, of course, the list of messages are lost and I have to re-query. I don't really like parcelable because I think it smells funny, but so does a static list. Any other ways to tackle this problem? Only other thing I can think of is a member on the Application class.
|
Mark M. |
in Android N, onRetainNonConfigurationInstance() and getLastNonConfigurationInstance() have been de-deprecated
|
Mark M. |
and I have been told that they are safe for use
|
Mark M. |
though if you are not inheriting directly from Activity, you should figure out how to interoperate with superclasses
|
Mark M. |
so, you could use those to hold onto model objects or other state that should survive a configuration change but would need to be reloaded if your process is terminated
|
Mark M. |
or, use a retained fragment
|
Mark M. |
even if that's just a model (headless) fragment
|
Michaelidle |
I'll take a look at onRetainNon... and getLastNon.... Are those two methods the way that rotation used to be handled back in the day?
|
Mark M. |
yes, pre-fragments
|
Mark M. |
when fragments were introduced, both of those methods were marked as deprecated, and you were steered towards retained fragments
|
May 10 | 9:15 AM |
Michaelidle |
Not a fan of the headless fragment approach... but it works I guess, so I may give it a shot. I've been using dagger as well, and have contemplated providing a List, and the List would be annotated with @Singleton so that it will stick around. Any thoughts on that approach? Not sure if you ever used Dagger. If not, then feel free to disregard the question.
|
Mark M. |
using singletons for a model cache is reasonable, but that only partially addresses configuration changes
|
Mark M. |
I would not be a fan of using singletons purely for configuration changes -- too likely to introduce memory leaks IMHO
|
Mark M. |
so, for example, saying that you have some sort of singleton LRU cache for messages is fine, but you still need to retain, across configuration changes, the identities of the messages that this particular activity needs
|
Mark M. |
now, perhaps your data model happens to be structured along clean enough lines that this is not an issue, particularly since Intent extras and stuff are automatically available in the new activity instance
|
May 10 | 9:20 AM |
Mark M. |
so, for example, an LRU cache of conversations might map neatly to your UI, where you are using an Intent extra or something to tell the detail activity which conversation it cares about
|
Mark M. |
but personally I try to keep "cache to avoid I/O" reasonably independent of "dammit, the user rotated the screen again" concerns
|
Michaelidle |
So, avoiding i/o and screen rotation, to you are two separate issues. Makes sense.
|
May 10 | 9:25 AM |
Michaelidle |
So my last question for today is if you have any tips when it comes to threading. I know that's a huge topic, but I find myself working in Activities or IntentServices, and making the same calls to some methods in both, and one happens on the main thread, and the other happens off. I constantly feel compelled to add a description of what thread the work will happen on to every method name.
|
Mark M. |
um, well, I can't really help you with your method-naming compulsion :-)
|
Michaelidle |
Example: I have a util or model class that does DB io, but when I'm calling it from an Activity, I want it to be off the main thread and handle the threading itself, but in my IntentService, I want it to be synchronous.
|
Mark M. |
that sounds like a broader architectural issue, but I don't know your app
|
May 10 | 9:30 AM |
Mark M. |
you might go with x() and xAsync() (e.g., load() does work synchronously, loadAsync() uses some background thread)
|
Michaelidle |
Do I just create two methods of anything that isn't synchronous? DBUtil.getListOfMessages(id) and DBUtil.getListOfMessagesAsync(id)? idk. I'm just having a hard time nailing down where I should be doing threading. In the upper most app components (Activity, Service) or somewhere else.
|
Mark M. |
where loadAsync() calls load()
|
Michaelidle |
I guess I just needed to vent about my frustration.
|
Mark M. |
well, the async edition would not have to duplicate the work of the sync edition
|
Mark M. |
it just needs to wrap the sync edition in some async logic
|
Michaelidle |
Yeah. Wouldn't be so bad. Thanks. It may be a fair thing to do in certain scenarios.
|
Michaelidle |
That's all I have for today. Thanks Mark.
|
Mark M. |
you are very welcome
|
May 10 | 9:35 AM |
Michaelidle |
You don't happen to have any kind of configuration steps for setting up Android Studio to build faster do you? Not sure if you have them in the book anywhere. Everywhere I look there are different suggestions on different AS args and stuff.
|
Mark M. |
well, the story tends to mutate based upon AS version
|
Mark M. |
and, so far, I haven't really had a big problem with this, so I have not spent the time trying to catalog all the possibilities
|
Mark M. |
Instant Run, of course, is Google's magic elixir in this space
|
Mark M. |
though that's only on AS 2.0+ and comes with its own set of caveats
|
Michaelidle |
Understood. Yeah, I wish there was just a canonical source for it. Like, "I have 16 gigs of ram. What should I do with AS?" Oh well. I'll try out the latest stuff from Retos video this past week. He made some changes to AS args in that video.
|
Michaelidle |
Any chance you'll add Rx type stuff to the book any time soon?
|
Mark M. |
not for any conventional definition of "soon"
|
Mark M. |
I'm not ruling out covering it someday
|
Mark M. |
I just don't think that it solves enough problems to be worthy of all the attention
|
May 10 | 9:40 AM |
Mark M. |
for example, with respect to our discussions today, Rx is oblivious to configuration changes and is oblivious to services
|
Mark M. |
at least, as far as I can tell from what I'm reading
|
Michaelidle |
Alright. Just asking. I want to get into it at some point soon. Just about any problem, library, or tool that I use, I wish there was a "Busy Coders Guide for X" for it. Haha
|
May 10 | 10:00 AM |
Mark M. |
OK, 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 office hours are Thursday at 7:30pm US Eastern
|
Mark M. |
have a pleasant day!
|
Michaelidle | has left the room |
Mark M. | turned off guest access |