May 19 | 7:25 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
EGHDK | has entered the room |
Mark M. |
hmmm... let's try this again...
|
Mark M. |
hello, EGHDK!
|
Mark M. |
how can I help you today?
|
EGHDK |
Hey Mark. Couple of rapid fire questions for ya
|
Mark M. |
go right ahead
|
EGHDK |
1st. Trying to make sure I don't cause any memory leaks. Is this statement correct? "An annonymouse inner class always holds a ref to the outer class."
|
Mark M. |
yes
|
Ken | has entered the room |
EGHDK |
If activity has button.setOnClickListener(new OnClickListener) isn't that anonymous inner class holding onto the outer class?
|
May 19 | 7:30 PM |
Mark M. |
yes
|
Ken |
Hello, everyone.
|
EGHDK |
So why don't I do anything onDestroy()?
|
Mark M. |
(hello, Ken -- I will be with you shortly!)
|
Mark M. |
EGHDK: because you don't need to
|
Mark M. |
the outer class is the activity
|
Mark M. |
the activity holds the button, which holds the listener, which holds the activity
|
Mark M. |
it's a loop
|
Mark M. |
so the whole loop can get garbage-collected
|
EGHDK |
Yeah, so if the Activity gets destroyed... the button listener does NOT... right?
|
Mark M. |
listeners don't get "destroyed"
|
EGHDK |
Well, marked for gc?
|
Mark M. |
then yes, the listener should be eligible for GC
|
Mark M. |
again, the activity holds the button, which holds the listener, which holds the activity (the outer class instance)
|
Mark M. |
as soon as the activity can be GC'd, so can the button and listener
|
EGHDK |
So how would you cause a mem leak. Isn't every anonymouse inner class a loop? So I never have to worry about doing anything with them?
|
Mark M. |
"Isn't every anonymouse inner class a loop?" -- not necessarily
|
EGHDK |
Sorry, you just threw me off with the "loop" thing. I could have sworn that onDestroy()s super was doing something in the background to get rid of all my listeners and such.
|
Mark M. |
it's not necessary, so long as the activity can be garbage-collected
|
Mark M. |
let me take a question from Ken, and I'll be back with you shortly
|
Mark M. |
Ken: your turn! do you have a question?
|
EGHDK |
So a running thread... or asynctask would keep it from being gc'd right?
|
EGHDK |
No prob
|
Ken |
hi
|
May 19 | 7:35 PM |
Ken |
Mostly I just wanted to see if you are actually here. Seems you are. But I do have a question.
|
Mark M. |
I'm here, for some definition of "here". And some definition of "I'm". :-)
|
Ken |
I am fooling around with setting up a backend server from AS
|
Ken |
Mostly just copying code blindly at this point.
|
Ken |
But I have it working with the local version of the server, as long as I use the emulator
|
Ken |
I can't figure out how to do the same thing with the client running on an attached actual phone.
|
Mark M. |
"local version of the server" meaning running on your development machine?
|
Ken |
Do have any experience with this? Is targeted to the Google App Engine
|
Ken |
yes, exact.
|
Mark M. |
I have never used Google App Engine
|
Mark M. |
that being said, you need to make sure that your app uses an IP address that identifies your development machine, and that the app server is listening on that IP address
|
Mark M. |
for example, if the app server is listening only on localhost (127.0.0.1), an emulator running on your development machine could talk to that server, but a device could not
|
Ken |
The app server is listening on a a dummy address: 10.0.2.2:8080
|
Mark M. |
it needs to be reachable by the device
|
Ken |
I think, anyway.
|
Ken |
RIght.
|
Ken |
I can't think how to make it happen
|
Mark M. |
typically, that means that the device has to be on WiFi, and the server has to listen on an IP address that's for the same network
|
Ken |
Right. But
|
May 19 | 7:40 PM |
Ken |
The device is actually connected by USB.
|
Mark M. |
that does not help you
|
Ken |
no, but does it hurt?\
|
Mark M. |
it shouldn't
|
Ken |
Okay, well, let me look up some more stuff and get back to you.
|
Mark M. |
OK
|
Mark M. |
EGHDK: back to you! do you have another question?
|
EGHDK |
So a running thread... or asynctask would keep it from being gc'd right?
|
Ken |
I think I don't understand the Registration.Builder well enough.
|
Mark M. |
EGHDK: correct
|
EGHDK |
Anything else that would be an annonymous inner class that would hold a ref and make a mem leak?
|
EGHDK |
or are threads/runnables basically it?
|
Mark M. |
the same things that cause anything to be a memory leak: static data members and threads
|
Mark M. |
anonymous inner classes don't really change that
|
Ken |
[I'll be back-- some day. See you later]
|
May 19 | 7:45 PM |
Mark M. |
(Ken: OK!)
|
EGHDK |
Okay. so I guess I was looking at this wrong. Yes, anonymous inner classes have a reference to the outer class, but to cause a memory leak, a static member or thread would have to be misused.
|
EGHDK |
Is that a correct statement?
|
Mark M. |
correct
|
Mark M. |
yes
|
Mark M. |
now, occasionally, you will run into a case where the static reference is made by somebody else, not you
|
Mark M. |
this is the "don't make an anonymous inner subclass of Handler" problem
|
EGHDK |
Got it.
|
Mark M. |
Handler itself sets up a static reference
|
EGHDK |
Oh
|
EGHDK |
Alright
|
Mark M. |
listeners, though, are usually interfaces, and therefore there's no hidden code from a superclass that can bite you
|
EGHDK |
So whats the deal with AsyncTask. Does it create a static ref, or is it the threading part of asynctask that can cause a memory leak?
|
Mark M. |
AsyncTask uses a thread pool
|
Mark M. |
while that thread is running the task, nothing the task can reference can be garbage-collected
|
May 19 | 7:50 PM |
EGHDK |
gotcha. So since I can get the activity from an asynctask that means it can't be gcd
|
Mark M. |
I'd phrase it as "if I can get to the activity from the AsyncTask, then it can't be GC'd"
|
Mark M. |
there's nothing intrinsic to an AsyncTask that makes it tied to activities
|
EGHDK |
Whats the error you get if you try to update an activity that was destroyed from an asynctask?
|
EGHDK |
Is the error that the activity doesn't exist... or that the activity was destroyed already?
|
Mark M. |
there's probably a few possible exceptions
|
Mark M. |
I seem to recall getting a NullPointerException once
|
EGHDK |
True. I can look into that. No biggie.
|
Mark M. |
there's no specific ActivityGotNukedException, if that's what you mean
|
EGHDK |
So asynctask is pretty touchy in an activity. you want to make sure you keep that short, or at least end it onDestroy.
|
EGHDK |
AsyncTask is a little nicer in a Service then... huh?
|
Mark M. |
hang on
|
EGHDK |
because no lifecycle changes from config changes
|
EGHDK |
okay. *hanging*
|
Mark M. |
if by "end it onDestroy", you mean "cancel() it in onDestroy()", then yes, that's a good pattern
|
EGHDK |
Yep. That's what I meant.
|
Mark M. |
onPostExecute() will not be called on the task, if the task is still running, and you can call isCancelled() to see if you were canceled from within onProgressUpdate() if needed
|
Mark M. |
with respect to a service, there is usually no point to an AsyncTask, over a thread, in a service
|
Mark M. |
the point to AsyncTask is specifically to do certain work on the main application thread
|
May 19 | 7:55 PM |
Mark M. |
and you rarely want to do work in a service on the main application thread
|
EGHDK |
Let's say I wanted to make a broadcast, for an internal eventbus to my app. Doesn't a broadcast have to be made from the ui thread?
|
Mark M. |
no
|
EGHDK |
oh. that's not bad then.
|
EGHDK |
I guess I had that mixed up... maybe it's the broadcast receiver in my activity that has to be on the ui thread.
|
Mark M. |
sendBroadcast() on Context (for system broadcasts) and sendBroadcast() on LocalBroadcastManager (for local broadcasts) can be called from any thread
|
Mark M. |
the broadcasts are *received* on the main application thrad
|
EGHDK |
Thats pretty nice. Okay. Wasn't sure about that.
|
Mark M. |
er, thread
|
EGHDK |
Makes sense. Perfect.
|
EGHDK |
So asynctask... kinda pointless in a service then.
|
Mark M. |
right
|
EGHDK |
Would asynctask make sense to use in another class? Like I had a GCMTask that I used an asynctask in it. To start the GCMTask I took a context... but then internally, I always just did context.getApplicationContext()
|
Mark M. |
usually, you only use AsyncTask in conjunction with activities and fragments, because usually that's the only time when you have magic work (updating the UI) that has to be done on the main application thread
|
Mark M. |
there may be other use cases, but I can't think of any off the top of my head
|
May 19 | 8:00 PM |
EGHDK |
I implemented GCMTask as a singleton... and put an asynctask in it. Seems to work well (because I make a network call in the background) and on success of the network call I save some data. It just led me to believe that AsyncTask can be used in a class, but not in an Activity directly.
|
Mark M. |
why is that not just an ordinary thread?
|
EGHDK |
I'm not sure. I'd probably have to go back and look (I think) it's because google docs show gcm with asynctask... so i copied it
|
EGHDK |
That might be another question for another day though
|
EGHDK |
Got a couple of other questions to run through.
|
EGHDK |
Next is. I have a friend that I created a spiffy service for. I want him to integrate it into his App. I don't want to host it in a repo on jcenter. How would I send him something in an email, and have him use it in his project?
|
EGHDK |
I know theres jar, aar, or add a module
|
Mark M. |
are you using any resources or assets?
|
EGHDK |
No. No resources
|
EGHDK |
You mean xml or images... right?
|
Mark M. |
right
|
EGHDK |
It's just java
|
Mark M. |
stuff in res/ or assets/
|
Mark M. |
then a JAR, plus some instructions for how to add it to the manifest, would work
|
Ken |
[BTW] What's the deadline for soft typos for the next edition? I have a collection of suggestions, but I have been saving them up.
|
EGHDK |
Nope. Just java.
|
Mark M. |
Ken: my apologies! I am not paying attention and thought you left the chat!
|
Ken |
I did.
|
Ken |
He's back.
|
Mark M. |
OK
|
Mark M. |
Ken: to answer your question, there's no strict deadline, insofar as I make bug fixes continuously
|
Mark M. |
plus, I don't know the precise ship date for the next update, other than "early June"
|
Mark M. |
I'll have a better sense of it after Google I|O
|
May 19 | 8:05 PM |
EGHDK |
Cool. So I'm working in Android Studio and have a sample app, and in the same package as my sample activity, I have my service and one extra java class. How would I take my extra java class and service and create a jar?
|
May 19 | 8:05 PM |
Ken |
okay, that's good enough.
|
Mark M. |
EGHDK: there may be easier ways than this, but I create a custom Gradle task for it
|
Mark M. | |
Mark M. |
that's a Stack Overflow answer from Jake Wharton on creating custom Gradle tasks for generating a JAR from an Android library module
|
EGHDK |
Interesting. That'll work for me. Got a resource handy to point me towards? I would just make the jar in IntelliJ IDEA, because I know how to do that. But IntelliJ doesn't know about the android sdk I think, so I don't know how that would work.
|
EGHDK |
Okay. Thanks for the resource.
|
Mark M. |
IntelliJ certainly can know about Android -- there's the Android plugin for it
|
Mark M. |
I haven't used straight-up IDEA in a while
|
Mark M. |
let me take other questions from Ken for a bit, and I'll be back to you
|
Mark M. |
Ken: do you have other questions?
|
May 19 | 8:10 PM |
Mark M. |
EGHDK: back to you, then
|
EGHDK |
Yeah, but I just get confused, because I just feel like you can't create a jar that has Android APIs in it. Like some of my stuff is plain java, but the second I use Log.e() in my java class... I doubt that I'll be able to make it a jar.
|
Mark M. |
sure you can
|
Mark M. |
most of my CWAC libraries are available as JARs
|
EGHDK |
Okay, so I'll stop worry about that then.
|
Mark M. |
a regular Java program can't use those JARs
|
Mark M. |
but an Android app certainly can
|
EGHDK |
Got it.
|
Mark M. |
if you prefer, package the service as an Android library module, ZIP up the directory, and send that
|
EGHDK |
So if I just wanted to send it as a module,
|
EGHDK |
read my mind.
|
EGHDK |
so I have activity service and java class in one package. I want to send him service and java class as a module. Would I move the service and java class into a different directory and then zip that?
|
Mark M. |
if by "different directory" you mean an Android library module, yes
|
Mark M. |
your app would then depend upon that module, to pull in that code
|
Mark M. |
and you can distribute that module, such as via a ZIP file, far and proverbially wide
|
EGHDK |
Okay. I should be able to google that if anything. the jar info you gave me was gold though. thanks
|
May 19 | 8:15 PM |
EGHDK |
Okay.... 15 minutes. Got the rest of my list ready here. For instance, if you select NEW > Fragment in Android Studio to add a new Fragment, with """Include interface callbacks" checked, you'll get an interface inside of the Fragment class. The fragments interface is used so that you can do a click in the activity. But onDetach of the fragment you see the interface being set to null. Why is that?
|
Mark M. |
beats me
|
Mark M. |
I have never created a fragment through the wizard
|
Mark M. |
so I haven't looked at the code that it generates
|
EGHDK |
Okay. It is very interesting.
|
EGHDK |
The code that the service wizard generates is interesting as well.
|
EGHDK |
It creates static methods to "start" tasks for an IntentService. Thought it was interesting to see it done that way.
|
May 19 | 8:20 PM |
Mark M. |
yeah, I think I saw that code in a Stack Overflow question
|
Mark M. |
it's not a bad idea
|
Mark M. |
I have considered doing that for activities
|
Mark M. |
it's kinda like the factory method pattern
|
EGHDK |
Yeah. I liked it. Definitely take a look when you get more than 0.5 seconds of down time.
|
EGHDK |
Talking about patterns.... all of my next questions are on patterns. I'm reading a design patterns book. head first series. pretty good. and its java based, so easy for me to follow.
|
Mark M. |
I bought that book
|
Mark M. |
made it through a couple of dozen pages
|
Mark M. |
decided that the Head First style wasn't my cup o' tea... :-)
|
EGHDK |
One of the first lessons is to program to an interface not an implementation. I know interface doesn't mean "java interface" but now I want to make everything a damn interface. Is that good or bad? I know its kinda a silly question... but I never used interfaces before and they seem to make sense now.
|
EGHDK |
And yes, this is one of my least favorite in the head first series personally. I thought their java book was really good, their software development book was alright, but this one is hard to read.
|
Mark M. |
generally speaking, I tend to use interfaces (or sometimes abstract classes) in cases where I might want to use N different implementations of the same thing
|
EGHDK |
Okay. Yeah, I just feel like I'm getting interface happy over here.
|
May 19 | 8:25 PM |
Mark M. |
it's more important with libraries, IMHO, as the user of the library might want to plug in her own implementation of various things
|
EGHDK |
OnClickListeners... is that an observer pattern? Are all callbacks observer patterns in a nutshell?
|
Mark M. |
um, I forget how the Gang of Four defines the observer pattern, to be honest -- I tend to think of listener as being its own pattern
|
Mark M. |
OK
|
EGHDK |
Cool. I have my gof book sitting here. Just figured I'd go through the head first one to give me a good prep into gof.
|
Mark M. |
with observers, usually there's a collection of 'em
|
Mark M. |
in the case of most Android listeners, there's one one listener for the event
|
Mark M. |
IOW, it's setOnClickListener(), not addOnClickListener()
|
EGHDK |
Gotcha.
|
Mark M. |
so you can think of Android's use of listeners as being a limited implementation of the observer patern
|
Mark M. |
er, pattern
|
May 19 | 8:30 PM |
EGHDK |
Head First is releasing an android book in the next few months. I'm going to keep on top of those reviews. Interesting to see what people think of that book. Like I said before, I thought theyre Java book was gold. They explained something... and I would have a question and BAM they had my question written down with an answer. It's like they were reading my mind the entire time I read that book. super helpful.
|
Mark M. |
well, Kathy Sierra co-wrote Head First Java
|
Mark M. |
she's one of the best tech writers out there
|
Mark M. |
OTOH, she also co-wrote Head First Design Patterns
|
Mark M. |
which is why I assumed that it was the Head First style that bugged me
|
EGHDK |
Gotcha.
|
EGHDK |
Have you read HF java?
|
Mark M. |
no, mostly because I learned Java a long time ago
|
EGHDK |
I'll check out other kathy sierra books also. thanks for the tip
|
EGHDK |
I'm still looking for a place that'll print out the whole pdf of your book for a fair price. I just like reading in print too much.
|
Mark M. |
somewhere, a tree weeps
|
Mark M. |
(possibly a willow... :-)
|
EGHDK |
Being able to circle and underline things... and I love reading books fron to back, so even though I've jumped around your books and read a few hundred pages, I wish I could read it all.
|
EGHDK |
Oh man ba dum tsss. that was a good one.
|
EGHDK |
hahaha
|
Mark M. |
anyway, that's a wrap for today's chat
|
Mark M. |
next one is Thursday, also at 7:30pm US Eastern
|
EGHDK |
Okay mark. Hit all my questions today. Appreciate it. as always.
|
Mark M. |
have a pleasant day!
|
EGHDK | has left the room |
Ken | has left the room |
Mark M. | turned off guest access |