Mar 1 | 8:55 AM |
Mark M. | has entered the room |
Mar 1 | 9:00 AM |
Jumana A. | has entered the room |
Jumana A. |
Hi Mark!
|
Jumana A. |
HOpe you are well after your flu
|
Mark M. |
howdy, Jumana!
|
Mark M. |
I am a bit better, but this cold is still bothering me
|
Brent K. | has entered the room |
Jumana A. |
tell me about it!
|
Mark M. |
howdy, Brent!
|
Brent K. |
howdy!
|
Mark M. |
Jumana, you arrived first: do you have a question?
|
Jumana A. |
quick question - how do i implement a randomizer ...i want my app to pick up words randomly from a file
|
Jumana A. |
just tell me the classes and i can do the digging
|
Mark M. |
use the standard Java rand() function
|
Jumana A. |
oh !
|
Mark M. |
sorry
|
Jumana A. |
ok
|
Mark M. |
Random is a class
|
Mark M. |
java.util.Random
|
Jumana A. |
ya got it
|
Mark M. |
Brent: do you have a question?
|
Jumana A. |
also im having trouble installing updates on eclipse
|
Jumana A. |
sorry , Brent go ahead
|
Mar 1 | 9:05 AM |
Jumana A. |
im just posing the question before hand before my 2 year old pulls me away
|
Jumana A. |
seem to have some dependency issue when im updating eclispse 3.6.1 to 3.6.2
|
Mark M. |
I am no Eclipse expert, so it is unlikely I can be of much assistance
|
Jumana A. |
ok no prob, mark
|
Brent K. |
Ok, so I'm trying to figure out how to create
something like a "running operations" page for a file browser. When the
user initiates large operations, I want them to be able to view the
progress of those operations from a dedicated activity. File operations
are handled via asyncTasks of course.
|
Mark M. |
um, OK
|
Mark M. |
that's kinda broad
|
Mark M. |
do you have a more specific question>?
|
Mark M. |
(modulo a >)
|
Jumana A. |
picking up words randomly from a file in the
project directory structure and displaying on the screen are pure java
functionalities right, mark?
|
Brent K. |
lets see if I can be more specific
|
Mark M. |
Jumana: off the cuff, I would say yes
|
Mar 1 | 9:10 AM |
Brent K. |
Is there a way that I can make a second activity aware of any asyncTasks started by a first activity?
|
Mark M. |
more likely, those tasks should not be owned by either activity
|
Mark M. |
for the purposes of this chat, let's call the activity that is starting the tasks Activity A
|
Brent K. |
ok
|
Mark M. |
and the activity that is the list of running tasks is Activity B
|
Mark M. |
now, the user is in Activity A, they start off some task, and then press BACK
|
Mark M. |
what is the user's expectation in terms of whether that task should complete?
|
Brent K. |
Excellent question
|
Mark M. |
I kinda liked it myself... :-)
|
Mark M. |
if the answer is "the task should continue", then
you probably should be using an IntentService (if one task at a time is
sufficient) or a regular Service managing the AsyncTasks
|
Mar 1 | 9:15 AM |
Brent K. |
If, for example, the user decided to copy a ROM
file from one folder to another using my file explorer app, I think that
they would expect it to complete itself, even if the app had been
closed
|
Mark M. |
OK
|
Mark M. |
that calls for a Service of some form to be in charge of the work
|
Brent K. |
And it is entirely possible that there would be multiple operations going simultaneosly
|
Mark M. |
that would eliminate IntentService
|
Mark M. |
next question:
|
Brent K. |
This is good stuff. So I start up a service when I start my app, and pass any file operations to it from the main activity
|
Mark M. |
does the user need to be informed of task completion, even if there are no activities of yours running?
|
Jumana A. |
Thats it from my side as of now
|
Mark M. |
(Jumana: OK)
|
Brent K. |
That would probably be a good idea for at least
one of the different file operation types. Maybe my app could throw up a
notification if wasn't currently up?
|
Mark M. |
right
|
Mark M. |
my general recommendation would then be to use an ordered broadcast
|
Mark M. |
have the Service (or its AsyncTask) send an ordered broadcast when key events occur in the task lifecycle
|
Jumana A. | has left the room |
Mark M. |
(at least when the task ends)
|
Mar 1 | 9:20 AM |
Mark M. |
Activity B can register a high-priority receiver for the broadcast
|
Mark M. |
and if it gets the broadcast, it can update itself accordingly
|
Mark M. |
you also have a manifest-registered receiver for the same broadcast, at normal priority
|
Mark M. |
that receiver will only get control of Activity B wasn't around
|
Mark M. |
and it can display a Notification
|
Mark M. |
that way, the service is oblivious to whether Activity B is or is not around
|
Brent K. |
makes sense
|
Mark M. |
I blogged about this a ways back: http://commonsware.com/blog/2010/08/11/act…
|
Mark M. |
here's a sample project: https://github.com/commonsguy/cw-advandroi…
|
Mark M. |
and I'll finally be covering this in _The Busy Coder's Guide to Advanced Android Development_ in the next update
|
Mark M. |
now, in your case, the story is a bit more
complicated, as Activity B will somehow need to query to find out if
there are outstanding tasks
|
Mark M. |
there are a few approaches for that:
|
Mark M. |
1. have your service use the binding pattern (onBind()) and supply a query API
|
Mark M. |
2. have the roster of tasks as a static data member that Activity B peeks at
|
Mark M. |
3. have a ContentProvider interface to hide that static roster, and have Activity B use the Provider
|
Brent K. |
Activity B should also be able to remember
completed tasks too, so maybe the service can keep a running list
somewhere for Activity B to look at?
|
Mark M. |
in that case, I'd lean towards #3
|
Mar 1 | 9:25 AM |
Mark M. |
or #1
|
Mark M. |
well, actually, any of them could work for that, now that I think about it
|
Mark M. |
the disadvantage of #2 is that it implies that the
whole roster of completed tasks in is memory, which may or may not be
practical for you, depending on how much history you have
|
Brent K. |
True
|
emil10001 | has entered the room |
Mark M. |
Brent: let me take a question from emil10001, and I can swing back to you in a bit
|
tunneling | has entered the room |
Mark M. |
emil10001: do you have a question?
|
Mark M. |
(BTW, howdy, tunneling!)
|
tunneling |
hello
|
emil10001 |
hello Mark, I'm having an issue that I can't seem
to get rid of in my app, and I haven't had much luck getting it answered
elsewhere: http://stackoverflow.com/questions/9490558…
|
Mark M. |
first, apply StrictMode to see if you are doing
anything obviously wrong on the main application thread (disk I/O,
network I/O, etc.)
|
Mark M. |
then, use Traceview to see where your time is being spent
|
Mark M. |
(assuming StrictMode didn't identify your problem, that is)
|
emil10001 |
what does StrictMode do?
|
Mark M. |
StrictMode is covered in _The Busy Coder's Guide to Android Development_
|
emil10001 |
ah, ok
|
emil10001 |
i'll look it up there
|
Mark M. |
it will report if you try to do disk I/O, network I/O, and such on the main application thread
|
Mark M. |
Traceview is covered in _Tuning Android Applications_
|
Mar 1 | 9:30 AM |
emil10001 |
ok
|
Mar 1 | 9:30 AM |
Mark M. |
otherwise, it's really tough to give you general advice on this sort of problem
|
emil10001 |
I sort of figured that out, but I was stumped
|
Mark M. |
but if touch events are slow to respond, usually it's a matter of spending too much time on the main application thread
|
emil10001 |
well, i did try to break things off onto a service thread
|
emil10001 |
seemed to help a little bit, but not as much as I'd hoped
|
Mark M. |
yeah, that's where using Traceview can help, to more scientifically determine the source of your difficulty
|
emil10001 |
i'll look into StrictMode, and also see if I've done anything stupid in the UI thread
|
Mark M. |
OK
|
Mark M. |
tunneling: do you have a question?
|
emil10001 |
ok, sounds good, thank you
|
tunneling |
yea, i was wanting to disccus a little more the Plugin
|
tunneling |
I loaded up your sample code, and ran it in the emulator
|
Mark M. |
which sample is this?
|
tunneling |
works fine, i modified it to send over a ArrayList, works fine too
|
tunneling |
RemoveView
|
tunneling |
RemoteView
|
tunneling |
sorry
|
tunneling |
Host and Plugin
|
Frank | has entered the room |
tunneling |
Chapter 22 - Introspection and Integration
|
Mark M. |
tunneling: OK, what is your question?
|
Mar 1 | 9:35 AM |
tunneling |
is this pattern adequate for replacing an API?
|
Mark M. |
that's impossible to answer in the abstract
|
Frank |
Hi everybody!
|
Mark M. |
it's akin to asking if a brick is adequate for replacing a toothbrush
|
Mark M. |
(howdy, Frank!)
|
tunneling |
well, the last time we discussed this I was on the path of using ServiceLoader to load "drivers"
|
Mark M. |
it all depends on what the toothbrush was being used for
|
Mark M. |
right
|
tunneling |
so, where in the API i use a DriverManager to get a list of drivers
|
tunneling |
in the Plugin, I would broadcast an intent and get a list of available plugins
|
Mark M. |
the pattern I outline in the RemoteView samples can certainly be used for driver discovery
|
Mark M. |
whether ongoing communications with the driver
should be via broadcasts, or service commands, or service binding, or a
ContentProvider, is indeterminate
|
tunneling |
so it's possible to bind to a service from another app?
|
Mark M. |
sure: see Remote Services sections in the
"Advanced Services" chapter in _The Busy Coder's Guide to Advanced
Android Development_
|
Mar 1 | 9:40 AM |
tunneling |
ok, that should get me going. I was concerned with the "back and forth" being done with intents
|
Mar 1 | 9:40 AM |
tunneling |
thanks.
|
Mark M. |
Frank: do you have a question?
|
Frank |
Yes!
|
Frank |
First of all thanks for doing this when Western Europe is awake. I really appreciate it.
|
Mark M. |
that's why I try to rotate through a few different times
|
Mark M. |
(though usually the morning slot starts an hour later)
|
Frank |
View paste
|
Frank | |
Frank |
When the user is no longer actively using the App, I would like to Notify him.
|
Mark M. |
ha! we just got through talking about that
|
Frank |
How would you go about dealing with this?
|
Frank |
ah sorry I got here late
|
Mark M. |
I really wish Campfire would let people scroll through a bit of history from before they entered the room...
|
Mark M. |
anyway, ordered broadcasts are one solution for this problem
|
Mark M. | |
Mark M. |
sample code: https://github.com/commonsguy/cw-advandroi…
|
Frank |
Reading...
|
Mark M. |
and this will be covered a bit more in the next
update to _The Busy Coder's Guide to Advanced Android Development_,
which (hopefully) will be released next week
|
Mar 1 | 9:45 AM |
Mark M. |
your service would send an ordered broadcast at the completion of #2
|
Mark M. |
your activity, if it is in the foreground, would receive the ordered broadcast in #3 and update the UI
|
Mark M. |
your manifest-registered receiver for the same
broadcast -- which would only get control if the activity did not handle
the broadcast -- would raise a Notification
|
Frank |
Sounds great!
|
Frank |
Perfect
|
Mark M. |
Brent: do you have another question?
|
Brent K. |
At least one ;)
|
Mark M. |
go ahead with one
|
Brent K. |
I'm grappling with whether or not this "operation queue" should remember things that it has done before
|
Brent K. |
so the question is:
|
Brent K. |
If I decide that the app/service should not forget
completed operations whenever it is unloaded from memory, what would be
the best way to persist that?
|
Brent K. |
A small database?
|
Mark M. |
that's a likely candidate
|
Mark M. |
some sort of JSON or XML file could work as well
|
Mark M. |
I'm not a big fan of using SharedPreferences for structures like that
|
Brent K. |
Yeah, that doesn't seem like it would be the best idea
|
Mar 1 | 9:50 AM |
emil10001 | has left the room |
Brent K. |
So basically, I would wrap the service, its minions, and the database/JSON or XML file that it writes to in a content provider?
|
Brent K. |
which would provide a more abstract way of retrieving this stuff for Activity B?
|
Mark M. |
well, technically the service wouldn't be wrapped by the ContentProvider
|
Mark M. |
they would work more in tandem
|
Mark M. |
the ContentProvider would provide the API for manipulating your task queue and history
|
Mark M. |
the Service would be executing the tasks
|
Brent K. |
Would there be an easy way for Activity B to display realtime progress using this setup?
|
Mark M. |
use a ContentObserver, perhaps
|
Mark M. |
we're running a bit low on time
|
Brent K. |
I'll have to read up on those
|
Mark M. |
if anyone has other questions, fire away
|
Frank |
OK
|
Frank |
View paste
|
Mark M. |
the use of broadcasts to have a service notify
others is covered in _The Busy Coder's Guide to Android Development_ in
the theory chapter
|
Frank |
What are the pros and cons of this approach?
|
Frank |
ah ok, missed that
|
Mark M. |
I do not cover every possible permutation of options in the patterns, because I don't have that kind of time
|
Frank |
I only looked in the service patterns section.
|
Mark M. |
this will get more coverage in the next update to the Advanced Android book, as previously mentioned
|
Frank |
What are the pros and cons compared with the approaches you do cover directly in the service patterns?
|
Mar 1 | 9:55 AM |
Mark M. |
broadcasts are public, unless you are only supporting 2.2 and can use setPackage()
|
Mark M. |
broadcasts involve RPC (unless you use LocalBroadcastManager, also covered in the next Advanced Android update)
|
Frank |
broadcasts are 1-n, so there can be several receivers...
|
Mark M. |
that too
|
Frank |
Not sure if that's the case with the patterns in the book
|
Mark M. |
the book samples are more focused on 1-(0/1)
|
Frank |
It should become important when you have several Fragements onscreen, right?
|
Mark M. |
only if all those fragments care
|
Frank |
Well, if at least 2 Fragments care...
|
Mark M. |
and since fragments can't receive broadcasts, it's really more a question for their hosting activities
|
Frank |
Ah! I didn't know that!
|
Frank |
Well maybe Broadcasts are a bit of overkill then.
|
Mark M. |
well, there is no registerReceiver() on Fragment AFAIK
|
Jumana A. | has entered the room |
Jumana A. | has left the room |
Mar 1 | 10:00 AM |
Frank |
Thanks Mark. The Ordered Broadcasts are just what the doctor ordered!
|
Mark M. |
OK, that's a wrap for today's chat
|
Brent K. |
Thanks for the help Mark
|
Mark M. |
next week's are at 7:30pm Eastern (with appropriate apologies to Western Europe)
|
Frank |
Looking forward to the transcipt
|
tunneling | has left the room |
Brent K. | has left the room |
Frank | has left the room |
Mark M. | turned off guest access |