Mark M. | has entered the room |
Mark M. | turned on guest access |
Mar 6 | 7:30 PM |
Brent K. | has entered the room |
Mark M. |
howdy, Brent!
|
Mark M. |
how can I help you today?
|
Brent K. |
Evening Mark
|
Brent K. |
Well, I've been studying services and methods of communicating information between them and activities
|
Brent K. |
and I'm hoping to glean some wisdom on how best to provide that communication.
|
Brent K. |
so that said...
|
Mar 6 | 7:35 PM |
Brent K. |
Is it ok to both start and then bind a service?
|
Mark M. |
that's unusual, but supported
|
Brent K. |
I'm writing a file manager app
|
Mark M. |
why would a file manager app need any sort of service?
|
Brent K. |
and I want to offload file operations onto a background service in order to better handle long running file operations
|
Mark M. |
ah, OK
|
Brent K. |
So the service needs to persist past binding
|
Mark M. |
why do you want to both bind and start?
|
Brent K. |
just in case the app UI thread gets destroyed
|
Brent K. |
That would be the reason for starting (to my understanding)
|
Mark M. |
if "the app UI thread gets destroyed", your process was terminated, and your service is gone too
|
Brent K. |
Hmm
|
Mark M. |
the main application ("UI") thread is created when the process starts and lives until the process is terminated
|
Brent K. |
Am I getting mixed up between processes and activities?
|
Mark M. |
perhaps
|
Mark M. |
I can't read your mind :-)
|
Brent K. |
It's possible for the activity to be recycled while the service persists, correct?
|
Mark M. |
if you use startService() (and only startService()) the service is independent of any activity
|
Mar 6 | 7:40 PM |
Mark M. |
if you bind to a service, you need to unbind before the activity goes away
|
Mark M. |
personally, I can't conceive of a scenario where it makes sense to both start and bind
|
Brent K. |
Fair enough
|
Mark M. |
in your case, using an IntentService (or a regular
Service with a thread pool) for background ops makes sense, but I'd
just use start
|
Brent K. |
Best not to use an intent service, since I'd like to allow for concurrent operations
|
Mark M. |
then a Service and either a passel of AsyncTasks or your own thread pool
|
Brent K. |
Although, now that I'm thinking about it, concurrent file operations might create issues with simultaneous access...
|
Brent K. |
but regardless
|
Brent K. |
If what I'm aiming for is the reliable completion
of long running file operations, even if the user closes the app, I
should go for starting a service?
|
Brent K. |
(as opposed to binding)
|
Mark M. |
you definitely need to use startService() for your scenario
|
Mark M. |
and, if you bind to a service, you need to unbind cleanly (e.g., bind in onCreate()/unbind in onDestroy() of an activity)
|
Mark M. |
that's if you want to both start *and* bind
|
Mar 6 | 7:45 PM |
Mark M. |
which I don't know why you would want to do
|
Brent K. |
Are there concievable communication advantages with bind?
|
Mark M. |
for some definition of "conceivable", perhaps
|
Mark M. |
I would phrase it more as "use startService() alone, and mix in bindService() if and only if you have a clear need for it"
|
Mark M. |
and, off the cuff, I have no idea what that need would be
|
Brent K. |
I'm going to assume that means the use of both is far outside normal/best practices and focus on starting my service
|
Brent K. |
Ok. Now I already know how operation completion will be handled (via the ordered broadcast you helped me with previously)
|
Mark M. |
it's pretty unusual
|
Mark M. |
yup
|
Mark M. |
BTW, that's covered in greater detail in the Advanced Android update I released yesterday
|
Brent K. |
I'll check that out.
|
Brent K. |
So now I just need to get a handle on how best to allow the UI activity to provide realtime completion stats.
|
Brent K. |
In addition to keeping track of file operation history (likely via a db)
|
Mark M. |
what will be in the "realtime completion stats"?
|
Brent K. |
A progress bar, basically
|
Mark M. |
oh
|
Brent K. |
Maybe some accompanying numbers
|
Brent K. |
Like percentages or bytes moved, etc
|
Mark M. |
off the cuff, there, I'd use the Messenger approach I demonstrate in _The Busy Coder's Guide to Android Development_
|
Mark M. |
pass a Messenger, tied to your activity's Handler,
in an Intent extra on the "yo, download this, buddy" command you pass
to the Service
|
Mark M. |
Service updates the activity via the Messenger
|
Mar 6 | 7:50 PM |
Brent K. |
Sounds like what I'm looking for.
|
Mark M. |
for events the user needs to know about beyond
that, use the ordered broadcast, or try the Messenger and raise a
Notification if you get the RemoteObjectException
|
Mark M. |
another possibility, if you want to stick to broadcast, is to use a LocalBroadcastManager instead of the Messenger
|
Mark M. |
that's also covered in yesterday's update to the Advanced Android book
|
Brent K. |
ok
|
Mark M. |
you don't want to use true broadcasts for frequent stuff, as there is IPC overhead on each broadcast, so it gets a bit expensive
|
Brent K. |
That's kinda what I was thinking
|
Mark M. |
so I wouldn't update byte counts using a regular sendBroadcast()
|
Mark M. |
but a LocalBroadcastManager, or Messenger, are cheap
|
Brent K. |
That is exactly the info I was looking for
|
Brent K. |
I love all of the sample code that you provide. There is no substitute for reading the code of experienced programmers
|
Brent K. |
best way to actually understand best practices
|
Mark M. |
glad it's proving useful
|
Brent K. |
On a side note, not sure if you keep up with the progress on ActionBarSherlock, but it's rapidly approaching completion
|
Mar 6 | 7:55 PM |
Mark M. |
yup, it's going to be a key piece of The Big Book Reboot
|
Brent K. |
I feel like Jake is singlehandedly matching Google's efforts towards encouraging the modernization of new and existing apps.
|
Mark M. |
Jake is awesome
|
Brent K. |
Here's another question for you:
|
Brent K. |
I'm going to be faced with passing complex packages of data from my activity over to my service
|
Brent K. |
Like a list of files to be copied and the destination directory, for example
|
Brent K. |
I'm assuming communication would be via intent?
|
Mark M. |
with startService(), yes, you package your command as extras on the Intent
|
Brent K. |
And if so, How can I package that information into something that can be handled via intent?
|
Mark M. |
for complex structures, either use stuff that go
in Intent extras (e.g., string arrays), or use Bundle, or make a class
that implements Parcelable
|
Brent K. |
From what I have been able to learn so far, I think Parcelable might be my ticket
|
Mar 6 | 8:00 PM |
Brent K. |
Is that basically like serializing the object?
|
Mark M. |
yes, though the results cannot be persisted
|
Mark M. |
basically, they skip the versioning info
|
Mark M. |
assuming it's only being used temporarily
|
Brent K. |
hmmm
|
Brent K. |
I'd like the service to be working with it's own instance of the data, in order to be separate from the activity
|
Brent K. |
That possible?
|
Mark M. |
if you are passing stuff via the Intent, they will be copied
|
Brent K. |
Even an entire object parcel?
|
Mark M. |
yes
|
Brent K. |
That works then
|
Brent K. |
I'm thinking of gathering all relevant information, flags and files into "pasteRequest" and "zipRequest" objects
|
Brent K. |
that are passed over and used by paste and zip operations
|
Brent K. |
within the service
|
Samuel | has entered the room |
Mar 6 | 8:05 PM |
Brent K. |
Time to take the backseat
|
Brent K. |
Hey Samuel
|
Mark M. |
howdy, Samuel!
|
Samuel |
Hello
|
Mark M. |
Samuel: do you have a question?
|
Samuel |
Yes. I got this error : 'close() was never
explicitly called on database
'/data/data/com.samuel.find_resto/databases/Resto' but it's happen when I
query data from web server using REST. If I delete the query the error
is gone. The application still running normally even though the error
exist.
|
Samuel |
Can I ignore it?
|
Mark M. |
first, it is a warning, not an error -- it should be colored yellow-orange, not red
|
Samuel |
It's red
|
Mark M. |
I have never seen that reported as an error
|
Mark M. |
I would simply try to close the database when you are done with it
|
Mark M. |
if your database is managed by a ContentProvider, you won't be able to do that
|
Mark M. |
but if you are accessing a SQLiteDatabase outside
of a ContentProvider, call close() on it when you are done with it and
any Cursors you retrieved from it
|
Mar 6 | 8:10 PM |
Samuel |
I use sqllite and I'm sore I have closed it
because if I pass the the code for querying data from web server, the
error will not raise.
|
Mark M. |
then I cannot help you
|
Samuel |
Ok, thanks for your time. I think I'll ignore it.
|
Samuel |
God bless you all.
|
Samuel |
It's enough for now.
|
Samuel |
Bye
|
Mark M. |
Samuel: have a pleasant day!
|
Mark M. |
Brent: do you have another question?
|
Brent K. |
Trying to think if I'm forgetting anything
|
Brent K. |
Ooo! yes. Is it possible to use both a background color overlaid with a semi-transparent striped png on the action bar?
|
Mar 6 | 8:15 PM |
Mark M. |
beats me
|
Mark M. |
I have never tried styling the action bar
|
Brent K. |
Haha, ok
|
Mark M. |
that being said, you can only have one background, in all likelihood
|
Mark M. |
which means you will need to use a LayerListDrawable if you really want those alpha-composited
|
Mark M. |
how well that will work when styling an action bar's background, though, I can't say
|
Mark M. |
stripes, though, sound a bit retro :-)
|
Brent K. |
Probably not that well
|
Brent K. |
The action bar is a bit of a black box
|
Brent K. |
and it's not too retro, lol
|
Mark M. |
well, you could use Theme.Holo.Light, in which case it's a bit of a white box :-)
|
Brent K. |
Nice classy diagonal pinstripes
|
Brent K. |
har har :-)
|
Mark M. | |
Mark M. |
that's the canonical documentation for action bar styling AFAIK
|
Mark M. |
(http://developer.android.com/guide/topics/… also has stuff, but it's a bit light on prose)
|
Brent K. |
I've been able to get that far
|
Brent K. |
Not sure if you can view this, but: https://mail-attachment.googleusercontent.…
|
Mark M. |
no, sorry, that's an attachment in your Gmail inbox AFAICT
|
Brent K. |
If you notice the colored highlights, I was thinking of ways to make it easily user configurable.
|
Mark M. |
fortunately for you, I can't read your mail
|
Mar 6 | 8:20 PM |
Brent K. | |
Brent K. |
There we go
|
Mark M. |
seems awful black for a file named blue
|
Brent K. |
Well, when the little bit of blue is the only
distinguishing feature of the blue, green, gold and transparent
versions, you gotta work with what you got
|
Mark M. |
setBackgroundDrawable() exists on ActionBar
|
Mark M. |
in principle, calling that with a LayerListDrawable (to blend your color and stripes) could work
|
Brent K. |
I'll look into that
|
Brent K. |
probably not the most critical element of my development
|
Mark M. |
well, that depends
|
Mark M. |
if your APK might be a bit large, they say stripes can cause a slimming effect... :-)
|
Mark M. |
(of course, I think that's for vertical stripes)
|
Mark M. |
any other questions from either of you?
|
Mar 6 | 8:25 PM |
Brent K. |
I think that's it for me
|
Brent K. |
You've given me weeks of things to think about
|
Mar 6 | 8:30 PM |
Samuel | has left the room |
Mark M. |
well, that's a wrap for today's chat
|
Mark M. |
next one is Thursday, also at 7:30pm Eastern
|
Mark M. |
have a pleasant day!
|
Brent K. |
Thanks Mark!
|
Brent K. | has left the room |
Mark M. | turned off guest access |