Nov 11 | 7:20 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Nov 11 | 7:40 PM |
EGHDK | has entered the room |
Mark M. |
hello, EGHDK
|
Mark M. |
how can I help you today?
|
EGHDK |
Hey Mark. So I'm still reading my intro to java book combined with watching some tutorials online and I just have a java question that I think you can explain to me.
|
Nov 11 | 7:45 PM |
Mark M. |
OK
|
Nov 11 | 7:45 PM |
EGHDK |
So I was watching an android tutorial on how to do network calls. And the tutorial showed the pre honeycomb the network call worked on the main ui thread, but post HC you need to do it off the main thread.
|
EGHDK |
The first thing the tutorial shows (before he goes into an asynctask) was he showed how to create a new java thread.
|
EGHDK | |
EGHDK |
I understand that I use asynctasks in Android, but I want to learn "threads" as well.
|
EGHDK |
And I guess I just don't get how that code above actually compiles.
|
Mark M. |
OK
|
EGHDK |
how does the compiler know what "new Thread()" means. I feel like I've never encountered that. Thread myThread = new Thread(); makes more sense to me.
|
Mark M. |
first, on the Android front, the tutorial should have indicated that it was a really bad idea to do the network call on the main application thread, and that they just started beating you on the head for it with API Level 14
|
Mark M. |
now, onto the Java
|
Mark M. |
let's take a simpler scenario
|
Mark M. |
int i=1;
|
Mark M. |
this assigns 1 to a variable (or data member) named i
|
EGHDK |
yep
|
Nov 11 | 7:50 PM |
Mark M. |
and you usually see numbers used in situations where it is part of a larger statement, like as a parameter to a method (e.g., object.foo(1);)
|
Mark M. |
however, the Java statement 1; is perfectly legal
|
Mark M. |
it doesn't do much
|
Mark M. |
and perhaps would be optimized away by the compiler
|
Mark M. |
oh, wait
|
Mark M. |
sorry
|
Mark M. |
that doesn't work with primitive values like ints
|
Mark M. |
scratch that
|
EGHDK |
Eclipse complain about `1;`, but maybe that's just eclipse.
|
EGHDK |
oh Okay. Cool Eclipse: "The left-hand side of an assignment must be a variable"
|
Mark M. |
let's try this again from the top
|
Mark M. |
String foo="bar";
|
EGHDK |
No prob. If anyone is gonna make sense out of this to me... it's gonna be you.
|
Mark M. |
"bar" here is a literal String object
|
Mark M. |
which we assign to foo
|
Mark M. |
but the key is that "bar" is an object
|
Mark M. |
all we do with String foo="bar"; is give the object a name by which we can reference it later
|
Mark M. |
(and create a reference, of relevance for garbage collection, but beyond the scope of this explanation)
|
EGHDK |
"bar" is an object? or is foo an object?
|
EGHDK |
Or both... technically.
|
Mark M. |
"bar" is an object
|
Mark M. |
foo is the name of a variable
|
EGHDK |
Gotcha.
|
Mark M. |
in conversation, we will say that foo is an object, but that's a bit of shorthand
|
Mark M. |
the more accurate thing would be: foo points to an object, initially "bar"
|
EGHDK |
Crystal clear.
|
Mark M. |
now, "bar"; is not a valid Java statement on its own
|
Mark M. |
just as 1; wasn't
|
Mark M. |
(for which I again apologize -- in some languages, it is a valid statement, just not Java)
|
Jeff | has entered the room |
Mark M. |
but "bar".length(); *is* a valid Java statement
|
EGHDK |
Quite alright.
|
Nov 11 | 7:55 PM |
Mark M. |
we are calling the length() method on the "bar" object
|
Mark M. |
(hello, Jeff, I will be with you shortly!)
|
EGHDK |
hmm.. Did not know that.
|
Mark M. |
EGHDK: now, in this case, nothing much happens, because length() does not modify "bar"
|
Mark M. |
nor does it have any other side effects
|
Mark M. |
which is why you do not see Java statements like "bar".length(); in use, even though they are legal
|
Mark M. |
now, suppose we have a statement: new Restaurant().open();
|
Mark M. |
this too is a valid Java statement
|
Mark M. |
we are creating an instance of a Restaurant instance, and calling open() on it
|
Mark M. |
depending on what open() does, this may be useful, even if we are not assigning the Restaurant, or any return value from open(), to a variable
|
Mark M. |
for example, open() might stick the Restaurant in some static collection of Restaurant objects
|
Mark M. |
so you will see that construction a bit more in Java, though it is still relatively uncommon
|
Mark M. |
one of the few places where you will see that more often, ironically, is the scenario that caused you confusion: new Thread() { public void run() {} }.start();
|
Mark M. |
because calling start() on a Thread starts the OS thread
|
Mark M. |
now, if we needed to refer to this Thread later on, we would be well advised to hold onto it somewhere
|
Nov 11 | 8:00 PM |
EGHDK |
OS thread?
|
Nov 11 | 8:00 PM |
Mark M. |
operating system thread
|
Mark M. |
threads are a construct of an operating system
|
Mark M. |
just as files are a construct of an operating system
|
EGHDK |
Interesting. Didn't know that either.
|
EGHDK |
Gotcha. So last thing about Thread that I don't 100% understand, and I feel like I've seen it in other places too. new Thread(){ public void run(){} }.start();
|
Mark M. |
languages *expose* threads and files to programmers
|
EGHDK |
Why is it not new Thread().run()?
|
Mark M. |
actually, let me take a question from Jeff, and I'll return to your run() vs. start() question in a moment
|
Mark M. |
Jeff: do you have a question?
|
EGHDK |
No prob
|
Jeff |
yes
|
Jeff |
2 quick ones
|
Mark M. |
OK, give me the first one
|
Jeff |
1. about a month you and I swapped some email about a problem with the new Droid mini crashing the camera code. I might be presenting camera code to the NYC Android meetup so I wondered if you looked into it more
|
Jeff | |
Mark M. |
that device demands activation on the Verizon network
|
Mark M. |
I bought one from Amazon, then couldn't do a damn thing with it, so I returned it
|
Jeff |
ah - I got it working with rotation after the picture
|
Jeff |
but the garbage collection takes several seconds which sucks
|
Jeff |
question 2
|
Mark M. |
yes, I'm looking into switching my own rotation code to NDK (or perhaps Renderscript) for similar reasons
|
Jeff |
I don't like post-rotation but it seems unavoidable in some circumstances
|
Jeff |
question 2
|
Nov 11 | 8:05 PM |
Jeff |
I'm using ProgressBar and SeekBar now. Is there some enhanced version with increments on the bars, etc?
|
Mark M. |
you mean, tick marks?
|
Jeff |
yea, like an old school number line
|
Mark M. |
nothing in the SDK
|
Mark M. |
possibly there's a third-party one that offers it
|
Mark M. |
try AndroidViews.net and see if one shows up there
|
Jeff |
I can build it but feels like someone should have solved it
|
Jeff |
thanks
|
Mark M. |
EGHDK: back to you
|
EGHDK |
So my question isn't really run vs start, more of a "Putting brackets after a new Object() doesn't make sense to me. To me that shouldn't work".
|
Mark M. |
ah
|
EGHDK |
Or does that type of thing have a name that I don't know. Because if I can pin a name to it... then it would make more sense to me I think.
|
Mark M. |
hold on one moment while I look up something to help with the explanation...
|
EGHDK |
Thanks
|
Mark M. |
OK, let's imagine that we had: new Thread().start();
|
Mark M. |
start() starts the OS thread, and arranges to call the run() method of the Thread on that OS thread
|
EGHDK |
Okay. Makes sense.
|
Mark M. |
the problem is that the built-in run() of Thread is not that useful on its own
|
Mark M. |
so we need run() to do something meaningful
|
Mark M. |
one approach is to create a subclass of Thread, with a better run() method
|
Mark M. |
e.g., class MyThread extends Thread { public void run() {} }
|
Nov 11 | 8:10 PM |
Mark M. |
then, new MyThread().start(); would run my overridden run() method
|
EGHDK |
Yep
|
EGHDK |
Got it
|
Mark M. |
in addition to regular Java classes, using the extends keyword, Java supports "anonymous inner classes"
|
Mark M. |
these are effectively throwaway classes, designed to be used to instantiate just one object of that class
|
Mark M. |
the syntax is a mashup of declaring a regular class ({ public void run() {} }) and instantiation (new keywoard)
|
Mark M. |
er, keyword
|
Mark M. |
so, new Thread() { public void run() {} }.start() is saying:
|
Mark M. |
first, we are creating an anonymous inner class, extending Thread, we we override the run() method
|
Mark M. |
second, we are creating an instance of that class
|
Mark M. |
third, we are calling start() on that instance
|
Mark M. |
this is not especially newcomer-friendly syntax
|
Mark M. |
but it works
|
EGHDK |
Okay, yeah. It does make sense though.
|
Mark M. |
note that you can create an anonymous inner class that implements an interface, instead of extending an existing class
|
Mark M. |
you will see that in a lot of Android examples, particularly with listeners
|
Mark M. |
button.setOnClickListener(new View.OnClickListener { public void onClick(View v) {} });
|
Mark M. |
View.OnClickListener is an interface, not a class
|
Mark M. |
but the same syntax works
|
EGHDK |
Yeah... well that's what I was gonna say. This "new Thread" thing reminded me of OnClickListeners, and those confuse the hell out of me.
|
Nov 11 | 8:15 PM |
EGHDK |
View class "implements" onCLickListener?
|
Mark M. |
let me take another question from Jeff, and I'll come back to you in a bit
|
Mark M. |
Jeff: do you have another question?
|
Mark M. |
OK, back to you, EGHDK
|
Mark M. |
OnClickListener is an interface
|
Mark M. |
it is implemented inside the View class
|
Mark M. |
much like how a regular inner class is implemented inside of another class
|
Mark M. |
and so, View here is serving as a bit of a namespace
|
EGHDK |
View paste
|
Mark M. |
correct
|
Mark M. |
OK, I misused "implements" a bit earlier
|
EGHDK |
I'm guessing KeyEvent.CallBack is onClickListener?
|
Mark M. |
let's try this again
|
Mark M. |
OnClickListener is an interface
|
Mark M. |
it is *defined* inside the View class
|
Mark M. |
KeyEvent.Callback is not an OnClickListener
|
Mark M. |
nor is Drawable.Callback, nor AccessibilityEventSource
|
Mark M. |
those three, and View.OnClickListener, are all interfaces
|
Mark M. |
View *implements* those three, meaning that View must have methods fulfilling all their contracts
|
Mark M. |
View *defines* OnClickListener inside of itself, and so other pieces of code can reference that interface as View.OnClickListener
|
EGHDK |
Interesting. I didn't know that you could define a interface inside of a class. I thought you had to define them in their own file.
|
EGHDK |
Thanks for clearing that up.
|
Nov 11 | 8:20 PM |
Mark M. |
you can define classes and interfaces inside of other classes (e.g., "inner classes") as well as in separate files
|
Mark M. |
Jeff: if you have another question, chime in
|
EGHDK |
Okay. My last question before times up. I am basically drawing two circles (Think ven diagram). I have 50% transparency on both. Right where they intersect... the image is darker (50% +50%). Is there anyway to stop this?
|
Mark M. |
beats me
|
EGHDK |
Not sure if that makes sense.
|
Mark M. |
my guess is no, and that regular color blending rules, including the alpha channel, will apply
|
EGHDK |
Heh. Okay. I thought I saw a video with Romain about doing that with Bitmaps... but I don't remember where I saw it.
|
Mark M. |
but that's just a guess
|
EGHDK |
Yeah, I know ROmain showed a way to do it with pictures. Because he had 4 pictures cascaded on top of each other. All transparent. But the blended in with each other. And he said that that wasn't the desired outcome. And he did something, and it layered the pictures... but still had transparency.
|
EGHDK |
Oh well. Guess it's time to look at old google i/o videos again. Thanks again mark. That finally makes sense to me. "Anonymous inner classes". Learn something new every day.
|
Mark M. |
you are not the first to complain about anonymous inner classes
|
Mark M. |
you probably won't be the last
|
EGHDK |
Yeah. I guess it wasn't a complaint. Just more of a "doesn't make sense because that's almost never ever used" type of thing.
|
Nov 11 | 8:25 PM |
Mark M. |
every language has its set of "power coder" syntax
|
Mark M. |
this happens to be part of Java's
|
EGHDK |
I guess I'll take it as that.
|
EGHDK |
I'm becoming a java power coder. Hahaha
|
Nov 11 | 8:30 PM |
Mark M. |
and that's a wrap for today's chat
|
Mark M. |
the transcript will be posted to http://commonsware.com/office-hours/ shortly
|
Mark M. |
the next chat is Thursday at 10am Eastern
|
Mark M. |
have a pleasant day!
|
Jeff | has left the room |
EGHDK | has left the room |
Mark M. | turned off guest access |