Mark M. | has entered the room |
Mark M. | turned on guest access |
Jul 31 | 4:00 PM |
Frank S. | has entered the room |
Mark M. |
howdy, Frank!
|
Mark M. |
how can I help you today?
|
Frank S. |
hey mark
|
Frank S. |
1 sec. I have to change rooms real quick
|
Frank S. |
I'm trying to animate a view pre 11 skd. And I'm
having a real problem with combining TransitionAnimations with
offsetLeftandright
|
Terence M. | has entered the room |
Mark M. |
howdy, Terence!
|
Mark M. |
Frank: I have not used offsetLeftAndRight
|
Terence M. |
Howdy do!
|
Frank S. |
aww pickels
|
Mark M. |
what is your overall objective? what are you using offsetLeftAndRight() for?
|
Jul 31 | 4:05 PM |
Mark M. |
and what's a skd?
|
Frank S. |
View paste
(80 more lines)
|
Frank S. |
**sdk
|
Mark M. |
setFillAfter() is almost always the wrong answer for whatever you're trying to do
|
Mark M. |
mostly because it does not change the actual touch positions
|
Mark M. |
it just changes where pixels get drawn
|
Mark M. |
usually, you need to do something in
onAnimationEnd() that actually makes your animation effect permanent, by
adjusting the layout
|
Frank S. |
ok. So that might actually work because I'm losing track of my pixels somewhere
|
Mark M. |
for example, if you are sliding something off the screen, make its visibility be GONE in onAnimationEnd()
|
Frank S. |
Yeah I tried to reset the offset, but it made the view jump to weird positions
|
Mark M. |
my desperately-needing-a-refresh Animation chapter covers that
|
Mark M. |
is this some sort of sliding menu?
|
Frank S. |
Trying to make a nice lib for the G+ and youtube sliding menu
|
Mark M. |
if you haven't done so already, Cyril Mottier has a multiple-post blog series on how he implemented one of those
|
Mark M. |
let me take a question from Terence, and I'll be back with you shortly
|
Mark M. |
Terence: do you have a question?
|
Jul 31 | 4:10 PM |
Frank S. |
yep. I got it to work perfectly with the new sdk 11 tools, but that doesn't work pre 3.0
|
Mark M. |
OK
|
Mark M. |
if either of you have a question, chime in
|
Terence M. |
I have a couple of questions referring to Tutorial 17, the one I was working on yesterday when I sent the mail
|
Mark M. |
ah, that mail
|
Mark M. |
OK, I'm with you
|
Mark M. |
go ahead
|
Terence M. |
yeah I'm a real trouble maker ;)
|
Terence M. |
Step 4 mentions needing to modify things to use
sendWakefulWork() rather than start service, however for the
DownloadCompleteReceiver the code listed looks the same as what I
already have pre-modification
|
Terence M. |
I checked the version current in the Repo and it's the same
|
Terence M. |
I modified the line to be: WakefulIntentService.sendWakefulWork(context, DownloadInstallService.class);
|
Mark M. |
which is correct
|
Terence M. |
everything seems to work, and the download
completes ok and installs but the notification about the download
remains in the bar even after you click it
|
Mark M. |
I am not sure how I messed up my copy
|
Terence M. |
I've only been working in the emulator since it
involves changing the clock so maybe it's just that, but I thought the
two might be related
|
Mark M. |
in your InstallReceiver, make sure you have setAutoCancel(true)
|
Jul 31 | 4:15 PM |
Mark M. |
in the chain of calls to the NotificationCompat.Builder
|
Tom | has entered the room |
Mark M. |
howdy, Tom!
|
Mark M. |
Tom: do you have a question?
|
Tom |
hi Mark
|
Tom |
Yes, I'm having problems with bind/unbind and wondering whether I should use startService instead.
|
Tom |
The first problem. My GUI calls bind and waits
for onServiceConnected() to be called before proceeding (e.g. cause it
doesn't even have access to preferences until it has its handle to the
service). In my service's onBind I send a message to defer doing my
initialization so I can return very quickly, but even that is not enough
to get my on onServiceConnected called - I think I'll have to send the
message with a delay.
|
Terence M. |
I think that may be in the next tutorial, I don't
see any mention of that here in #17. Is that something that will be
added in the notification tutorial coming up or have I messed up here?
|
Mark M. |
IMHO, your onBind() should be doing nothing but returning the Binder
|
Tom |
The second problem. When the user presses home
button, my activites onStop gets called and I unbind (I think I have no
choice - that onStop might be the last call my GUI gets). But now my
service shuts down (including killing all active network connections)
which is rather premature given that the user just pressed home (not
back). So, I'm going to add something to my service to stick around
another ~20 seconds after the unbind, but I feel like I'm fighting
against the bind/unbind mechanism again.
|
Mark M. |
Terence: no, you're right -- I was looking at the T-18 code
|
Jul 31 | 4:20 PM |
Mark M. |
Tom: what specifically are you trying to gain from
binding that you could not accomplish via the command pattern and
startService()?
|
Jul 31 | 4:20 PM |
Tom |
To tell you the truth, I can't remember why I chose to use bind/unbind rather then start.
|
Mark M. |
regardless, rather than calling unbindService() directly from onStop(), you could do the delay logic there
|
Mark M. |
use postDelayed() to post a Runnable to be invoked after 20 seconds
|
Mark M. |
if onStart() is called, cancel the Runnable
|
Mark M. |
if the Runnable gets to execute, have it do the unbindService()
|
Tom |
But if onStop has been called, and I delay before
calling unbind, then my activity could well get killed and I never call
unbind.
|
Mark M. |
if by "killed" you mean "destroyed", you could also unbindService() and cancel the Runnable in onDestroy()
|
Mark M. |
if by "killed" you mean "the process is terminated", your service is gone then too
|
Tom |
Yes, I meant destroyed.
|
Tom |
I thought there was no guarantee that onDestroy would be called.
|
Mark M. |
there isn't, but if it is not called, your process was terminated
|
Mark M. |
in which case, the issue is moot
|
Tom |
Ah, good point.
|
Mark M. |
moreover, your process can be terminated even if
you switched this to the command pattern and were doing the 20 second
delay in the service itself
|
Jul 31 | 4:25 PM |
Tom |
That resolves my issue#2 with bind/unbind, but
that still leaves issue#1 and has me still wondering whether there is
any disadvantage to switching to StartService instead.
|
Mark M. |
personally, I prefer startService() to bindService()
|
Mark M. |
so long as you know when to shut down the service
|
Mark M. |
that being said, shouldn't your initialization be in onCreate(), rather than onBind()?
|
Tom |
I wanted to move as much init as I could after
onCreate and onBind in the hopes of allowing the service to get started
and return from onBind as fast as possible.
|
Tom |
So that the app/gui could get its handle to the service.
|
Mark M. |
if onServiceConnected() is not being called at all, you have bigger problems, and I haven't the foggiest notion what they'd be
|
Tom |
It is being called, but it takes longer then I want.
|
Mark M. |
Tom: let me take some questions from the others, and I'll circle back to you
|
Mark M. |
Frank: do you have another question?
|
Tom |
Sure. Thanks.
|
Mark M. |
Terence: do you have another question?
|
Jul 31 | 4:30 PM |
Frank S. |
Nope. Just trying to get everything working again without fillenabled
|
Terence M. |
Not at the moment. Running a second time seemed to
clear things up but some other stuff has gone off the rails so I'm
going to have to poke more and see if I missed something
|
Mark M. |
Tom: OK, back to you
|
Mark M. |
the only reason I know of for onServiceConnected() to be delayed would be if you are tying up the main application thread
|
Tom |
View paste
|
Mark M. |
define "postpones all its initialization"
|
Mark M. |
are you using a background thread?
|
Tom |
Not using a background thread, but the onBind does
almost nothing other then post a delayed message (which later triggers
more initialization).
|
Mark M. |
define "post a delayed message"
|
Mark M. |
postDelayed() is a method on View; your Service does not have a View
|
Tom |
Just a sec - I'm checking the code.
|
Mark M. |
oh, it's also on Handler
|
Jul 31 | 4:35 PM |
Mark M. |
if you are using postDelayed() on Handler, that work in the Runnable is being done on the main application thread
|
Tom |
I'm sending an empty message to a handler.
|
Mark M. |
same thing -- handleMessage() is called on the main application thread
|
Tom |
Yes, the work is being done on the app thread - but after the delay which allows the binding to be completed.
|
Mark M. |
why would you even *want* the work to be done on the main application thread?
|
Tom |
Because there are quite a few interactions between
the GUI and the service and it simplifies those interactions if they
are in the same thread.
|
Mark M. |
frankly, you are scaring me with each passing entry in this chat... :-)
|
Tom |
All I/O is done in its own threads.
|
Tom |
Well, frankly, this whole architecture has become more complicated then it should be - certainly something needs to change.
|
Mark M. |
regardless, if onServiceConnected() is being
delayed, I believe reasonably strongly that it is because of work you
are doing on the main application thread
|
Mark M. |
to put it another way, I have no idea what else would delay it
|
Tom |
Ok, I accept that diagnosis - I just haven't
figured out how. But that is probably moot as I think I need to make
bigger changes.
|
Mark M. |
with regards to switching to startService(),
that's certainly possible, but you will need to choose how you want to
get info from the service back to an activity
|
Mark M. |
in terms of standard Android stuff, I'm a fan of LocalBroadcastManager from the Android Support package
|
Jul 31 | 4:40 PM |
Mark M. |
your service can send local broadcasts from a
background thread, and the activities can pick them up in the main
application thread
|
Tom |
Yes, I have started using LocalBroadcastmanager where possible.
|
Mark M. |
Otto, a library from Jake Wharton and the guys from Square, is another alternative, though I haven't tried it yet
|
Mark M. |
or, use regular broadcasts, a Messenger tied to your activity's Handler, etc.
|
Tom |
Okay, I'll take a look at that. I've also heard about this strict mode and been thinking I need to start using that.
|
Mark M. |
StrictMode certainly will yell at you if you stray
from the straight-and-narrow with respect to work on the main
application thread
|
Tom |
I have one more - much simpler - question, but perhaps you want to check with the others before I ask it.
|
Mark M. |
Frank, Terence: either of you have a question?
|
Terence M. |
nay, just soaking up info at this point
|
Mark M. |
OK, Tom, go ahead
|
Tom |
I believe that, if the system needs to load one of
my receivers, it must load (though not initialize) the entire app. So a
large APK with many activites take away from the efficiency of a tiny
receiver.
|
Tom |
Or does the system cache receivers?
|
Jul 31 | 4:45 PM |
Mark M. |
um, to some extent, neither :-)
|
Jul 31 | 4:45 PM |
Tom |
Does the system open my APK and just load the receiver from it?
|
Mark M. |
if you have no process, and a broadcast comes that
matches something in your manifest, Android will fork the zygote
process, then instantiate any ContentProviders of yours, then
instantiate your Application, then it will create your BroadcastReceiver
and call onReceive()
|
Mark M. |
notably, it will not load any classes not touched by those things
|
Mark M. |
hence, your activities and such should not impact matters
|
Mark M. |
now, if you have tons of initialization work in
onCreate() of a custom Application subclass, *that* price you will pay
on each process start
|
Mark M. |
which is one of the reasons I prefer static data members/singletons, as they will only get initialized when needed
|
Tom |
Okay, I do have a custom App subclass, but it is rather light-weight.
|
Tom |
Thanks Mark. Bye.
|
Jul 31 | 4:50 PM |
Mark M. |
if anyone has any questions, chime in
|
Terence M. |
I can't find the reference at the moment but I
think you mentioned that there's no "good" way to get a notification
from the DownloadManager for only a download that you started
|
Mark M. |
near as I can tell, you get all of them, which bugs the crap out of me
|
Terence M. |
or something to that effect, at any rate
|
Mark M. |
but it's been a bit since I looked at this issue
|
Terence M. |
is there a workaround mentioned in the book about how to hook into that in some way to sort of "fake" it?
|
Mark M. |
fake what?
|
Terence M. |
that may be the wrong choice of words.. to start a
download and be able to tell when you get a notification if it was one
that you started or not
|
Jul 31 | 4:55 PM |
Mark M. |
first, you'd keep track of your own pending downloads somewhere
|
Mark M. |
then, you'd use DownloadManager.Request to check the status of any pending downloads, and deal with those that are now completed
|
Mark M. |
or, use the extras on the ACTION_DOWNLOAD_COMPLETE broadcast, like EXTRA_DOWNLOAD_ID, and compare that to your downloads
|
Terence M. |
ahh ok, cool. I was afraid you had to check to see
if the file you thought you were downloading was there and complete
somehow or some such
|
Terence M. |
I thank you for the info sir, and the clarification on the sendWakefulWork() line.
|
Mark M. |
yeah, somehow I lost the one in the receiver, though the activity had it
|
Mark M. |
repairs will go out in tomorrow's Version 4.0 of the book
|
Jul 31 | 5:00 PM |
Mark M. |
OK, that's a wrap for today's chat
|
Mark M. |
next one is Thursday, 10am Eastern
|
Terence M. |
have a good evening, sir!
|
Mark M. |
have a pleasant day, all!
|
Frank S. | has left the room |
Terence M. | has left the room |
Tom | has left the room |
Mark M. | turned off guest access |