May 10 | 3:55 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Mark S. | has entered the room |
Mark M. |
howdy, Mark!
|
Mark M. |
how can I help you today?
|
Mark S. |
Nice to be here.
|
Justin M. | has entered the room |
Mark S. |
I've been looking through your code for quite awhile...
|
Mark S. |
and I've finally bought a Warescription. I am now a part of the team. I do have some questions.
|
Mark M. |
cool! ask one, and then we can give Justin (howdy!) a turn
|
May 10 | 4:00 PM |
Mark S. |
Your OrderedActivity demo design pattern covers about 73% of what I've been working through, which is quite remarkable.
|
Mark S. |
My main activity will be going through a cycle of tasks that are triggered by the repeating alarm.
|
Mark S. |
More accurately, the activity would be reminding the user of a task the user needs to do at that alarm time.
|
Mark S. |
What is the cleanest way to have the task index
increment, if the activity is in the background? I think I'm missing a
simple technique in which the notification manager can send a note to
the background activity to have it increment.
|
Mark M. |
the cleanest way is not to do it that way, IMHO
|
Mark S. |
I'm all ears.
|
Mark M. |
activities that are not in the foreground may not even exist, if Android terminated your process
|
Mark M. |
hence, there may not be an activity to update
|
May 10 | 4:05 PM |
Mark S. |
Good point. Can we catch that?
|
Mark M. |
instead, background activities should pull updated data when they return to the foreground, such as in onResume()
|
Mark M. |
as to where to put the task index, that would need to be in a persistent store (database, SharedPreferences, or other file)
|
Mark M. |
you might elect to cache it in a static data member, in the off chance that the process sticks around long enough to be reused
|
Mark M. |
and, you might use the ordered broadcast pattern to trigger an update of the foreground activity, if you have one
|
Mark S. |
SharedPreferences were what I was thinking of. Glad to get a confirmation, although I'
|
Mark S. |
I'll try the static member approach as well.
|
Mark M. |
let me take a question from Justin, and I'll swing back to you in a bit
|
Mark S. |
Thanks. I'll send my next question later on.
|
Mark M. |
Justin: do you have a question?
|
Justin M. |
Hey there Mark..
|
Justin M. |
Sort of...
|
Justin M. |
I've asked about Parcelable before. I know it's used for IPC with bound services....
|
Mark M. |
(not just bound services)
|
Justin M. |
I know someone on my team is trying to use it to pass complex objects between activities in Inents
|
Justin M. |
Intents
|
Justin M. |
I can't see where anyone is doing that
|
Mark M. |
I do not completely understand what you mean by "I can't see where anyone is doing that"
|
May 10 | 4:10 PM |
Justin M. |
OK, fair enough. Just been searching Google for
examples of people using Parcelables to package up complex objects to
pass between Services to Activities, or between Activities
|
Mark M. |
oh
|
Mark M. |
well, I definitely know people are using it, as I see questions on it from time to time
|
Tom O. | has entered the room |
Mark M. |
I do not think that it is a terribly popular approach
|
Justin M. |
It seems like it could be a bad approach
especially with really complex objects whose data you aren't even going
to be completely using....
|
Justin M. |
By bad I mean it will be slow
|
Mark M. |
"slow" is a relative term
|
Justin M. |
Agreed
|
Mark M. |
it will be way faster than persisting them to disk, for example
|
Justin M. |
So using a parcelable for this wouldn't necessarily be an incorrect approach then?
|
Justin M. |
That's really what I'm trying to determine
|
Justin M. |
Was that the intent (no pun intended) of parcelable usage?
|
Mark M. |
Parcelables in Intent extras is a code smell IMHO,
but not because it is Parcelable, but rather because it is a custom
Parcelable, suggesting that the model layer needs a bit o' work
|
Justin M. |
To pass complex objects around anywhere? Not just for IPC?
|
Mark M. |
Parcelable is used in IPC, but not just bound services
|
Mark M. |
Bundle is Parcelable
|
Mark M. |
PendingIntent is Parcelable
|
Mark M. |
RemoteViews (think app widgets) is Parcelable
|
Mark M. |
those don't scare me much
|
May 10 | 4:15 PM |
Justin M. |
So it's meant for IPC, but if I'm passing data
from a service to an activity in the same process, I'm not using IPC, so
does it still make sense? I don't want to use something just because
it will work, but rather because it was intended for that purpose.
|
Justin M. |
And if it isn't, I'd like to know what the proper tools are to use
|
Justin M. |
That's really my question
|
Mark M. |
can you give me a somewhat more concrete example of what one of these Parcelables would be?
|
Justin M. |
It would contain lists of complex types, like List<AComplexClass>
|
Mark M. |
OK, then what is AComplexClass?
|
Justin M. |
It would have a lot of primitive member types, maybe some more List<T> objects as well
|
Mark M. |
OK, this isn't working...
|
Mark M. |
let's try this...
|
Mark M. |
suppose you were creating an app that was displaying restaurants
|
Mark M. |
you have a ListActivity to show the restaurants
|
Mark M. |
you have a separate activity to show information about a restaurant
|
Mark M. |
and you have a service that does something in the background related to the restaurant
|
Mark M. |
none of those components should "own" a restaurant
|
Mark M. |
there should be something else that manages the restaurants, outside of these components
|
Mark M. |
so an activity would not pass a restaurant to a
service, but pass an identifier that would allow the service to go get
the restaurant that is needed
|
Justin M. |
out of a content provider or just a sqlite database
|
Justin M. |
right?
|
Mark M. |
or some sort of POJO cache, perhaps in a RestaurantManager singleton
|
Mark M. |
backed by a content provider or SQLite database
|
Mark M. |
or JSON file
|
Mark M. |
or "the cloud"
|
Mark M. |
or whatever
|
May 10 | 4:20 PM |
Justin M. |
In your example, they're trying to put the POJO into the intent using Parcelable and pass that from the service to the activity
|
Mark M. |
and if the POJO is part of the model of the app, I wouldn't do that
|
Mark M. |
now, if the POJO is, say, the contents of a
lengthy form that the user filled in (e.g., complex search criteria),
where it is not part of the model, then a Parcelable wouldn't faze me
too much
|
Mark M. |
(though I'd probably just use a bunch of individual Intent extras in that case)
|
Mark M. |
noodle on that a bit, let me take questions from others, and I'll swing back to you
|
Mark M. |
Tom: do you have a question?
|
Justin M. |
OK, that's what I wanted to know. I've been
taking the approach of having the service put the relevant data into a
database and passing an ID from the service to the activity. I like
your explanation of good usage, I'm good now, thanks.
|
Tom O. |
Just curious about some stuff regarding the lifecycle of a fragment
|
Tom O. |
In particular setRetainInstance()
|
Tom O. |
As I think about it, I have visions of leaks happening with careless use of .setRetainInstance(true).
|
Tom O. |
is there any sort of guidance?
|
Mark M. |
um, well, not really
|
May 10 | 4:25 PM |
Mark M. |
I mean, I don't know how to address abstract "visions of leaks"
|
Mark M. |
can you be a bit more specific about your concerns?
|
Tom O. |
Well, if the fragment instance isn't destroyed, it
becomes "orphaned" does it not? I mean, there is an instance of a
fragment that isn't associated with an Activity.
|
Mark M. |
no
|
Mark M. |
setRetainInstance() only matters with configuration changes
|
Tom O. |
Ahhhhh! That makes more sense now.
|
Mark M. |
once the activity is permanently destroyed (e.g., BACK button), the retained fragment goes "poof"
|
Mark M. |
(though you need to supply your own "poof" sound effect)
|
Tom O. |
I thought that when the activity is destroyed, the fragment could, in theory, live on.
|
Mark M. |
nope
|
Mark M. |
Mark: do you have another question?
|
May 10 | 4:30 PM |
Mark M. |
OK
|
Mark S. |
Yes. I have an app that uses a mapview, but uses
it in two activities. In the main activity, the mapview takes up the
entire screen, and in a separate activity, the mapview takes up a small
portion. When I go from my 2nd activity to my first...
|
Mark M. |
Justin: do you have another question?
|
Justin M. |
I'm still noodling :-)
|
Mark M. |
Mark: please continue (though you can't have two activities with a MapView in a process)
|
Mark S. |
That might partially explain my issue. When I go from my main activity to activity number 2, everything's hunky dory...
|
Mark S. |
But when I backtrack to my first activity, the mapview no longer takes up the whole screen.
|
Mark S. |
The size of the mapview on the returned activity matches the smaller mapview on activity 2.
|
Mark M. |
Quoting the docs: "Only one MapActivity is
supported per process. Multiple MapActivities running simultaneously are
likely to interfere in unexpected and undesired ways."
|
Mark M. | |
Mark S. |
Well, this is certainly unexpected and undesired.
I'll do some redesign. I do have another question, but I'll get back
in the queue.
|
May 10 | 4:35 PM |
Mark M. |
yeah, the Google Maps add-on has lotsa warts
|
Mark M. |
Justin: you done noodling yet?
|
Justin M. |
OK, so let me ask this again about Parcelable....
|
Justin M. |
When making a class Parcelable and passing the
parcelable between process boundaries, is the only real purpose to
serialize and deserialize the object, or is there other things happening
as well? (not sure if that question is clear or not)
|
Mark M. |
AFAIK, it is just serialization
|
Justin M. |
OK, sounds good. No other questions for now. I'll chime in to get readded to the queue if something comes to mind
|
Mark M. |
OK
|
Mark M. |
Tom: do you have another question?
|
May 10 | 4:40 PM |
Tom O. |
No, just watching and learning. :)
|
Mark M. |
OK
|
Mark M. |
if anyone has any questions, chime in
|
Mark S. |
I got one.
|
Mark S. |
I've been looking for some example code that shows
the use of gestures to move objects around on a screen. Think of a
solitaire game, or chess, etc...
|
Mark S. |
Most examples I've seen deal with transposing an entire canvas, not an individual view.
|
Mark M. |
well, I have not done much outside of GestureDetector, which simply detects gestures and does not apply them
|
Mark M. |
I also ripped a drag-and-drop ListView
implementation out of the AOSP Music app a couple of years ago, but
because I don't grok all the touch events, I discontinued support for it
|
May 10 | 4:45 PM |
Mark M. |
the only code I have that resembles what you are describing is the drag-and-drop MapView one
|
Mark S. |
Examples are few and far between. My guess is
that one could create a collection of views that implement
GestureDetector methods.
|
Mark S. |
I'll take a look at your dNd MapView. And I'll get back in line for another question.
|
Mark M. |
you might create a collection of *containers* that do that, but I am skeptical
|
Mark M. |
and we're in a free-for-all mode right now, so feel free to ask away
|
Mark M. |
(BTW, the map sample is https://github.com/commonsguy/cw-advandroi…)
|
Mark S. |
Yeeha.
|
Mark S. |
Here's a simple one, regarding the precedence of
onRestoreInstanceState() and onResume(). I could figure this out myself
with some Toast calls (but I'm lazy). I hope that
onRestoreInstanceState() happens *before* onResume().
|
Mark M. |
I think you are correct, though I am not 100% certain -- let me check
|
May 10 | 4:50 PM |
Mark M. |
hmmmm...
|
Mark S. |
On a similar note, I've seen conflicting opinions
on the call to super.onSaveInstanceState() or
super.onRestoreInstanceState(). Should the super be called first?
Don't worry about that precedence. I'll do the Toast.makeText() thing
to figure it out.
|
Mark M. |
I am having difficulty tracking down when onRestoreInstanceState() is called
|
Mark M. |
my understanding is that it should be shortly after onCreate()
|
Mark M. |
with regards to chaining to the superclass in
onSaveInstanceState()/onRestoreInstanceState(), I do not expect it
matters whether you call that first or last
|
Mark S. |
Ok. Thanks, Mark!
|
Mark S. |
Thanks for the advice. I'll catch you at another office session some time.
|
Mark S. | has left the room |
May 10 | 4:55 PM |
Mark M. |
if anyone has a question, chime in
|
May 10 | 5:00 PM |
Tom O. | has left the room |
Mark M. |
well, that's a wrap for today's chat
|
Mark M. |
next one is 10am Eastern on Tuesday
|
Mark M. |
have a pleasant day!
|
Justin M. |
Great, see you then, take care!
|
Justin M. | has left the room |
Mark M. | turned off guest access |