Log in

Jun. 4th, 2014 @ 12:17 am A Moment Aside
About this Entry
Quake Logo
Hey, guys:

For those guys outta the loop, I've been working two jobs (sometimes seven days a week) for just over two years now. I doubt there are any loyal followers, but that's why there hasn't been much of an update. That aside, I wanted to take a couple seconds and share a new thought that I've had blooming.

The idea is that there are two kinds of actions. I know other philosophies and religions sorta take this on, but I came across it independently. They take it on as "active" and "passive" behavior. That's all still well and good. My actions are "giving" and "taking".

So, let's loop back up. I work a lot. In the beginning, they were "taking" actions. I couldn't contribute much when I started at Millennial. Now, I think it's a giving action. I'm pretty sure I'm putting in more than I'm getting out. And that's what generates fulfillment. Working at the library, needless to say, is a very giving action-- it's getting hard to answer that age-old question of why I'm still working there.

Now, there are limits. I'm not saying that doing something that's kinda painful for the advantage of others and giving up great swathes of your life makes fulfillment, but some margin of discomfort is totally rad. Letting others take advantage of you: that's a giving action for you and a taking action for them. Too much isn't healthy anywhere.

I'm working a little intuitively here. Let me spill some beans: "giving" actions are for the benefit of others. "Taking" actions are for your own benefit. Playing games, reading, watching TV, downloading music... that's all "taking." Writing (code or literature), I think, falls neatly down the middle. Giving actions are pretty much limited to doing nice things for others "just 'coz."

It's important to have a balance, and this is how I sorta dreamed this up: If you take art, literature, writing, and programming as a "giving" action, then "taking" actions can help with inspiration. For real. I went a great length of time coding games without playing them, and drawing for a webcomic[webcomic.com] without reading them, and I found that I was at a loss. Balancing it up totally helped keep me fresh, and, if I assume folks are inspired by the crap I do (this is all conjecture, since my stuff is largely irrelevant to most decent people), then a bigger, communal kind of balance can happen.

Anyway, I'm not particularly good at philosophy or motivational speaking. Feel free to tell me I'm nuts.
Jun. 4th, 2014 @ 12:03 am Another One-Up for Homoiconicity
About this Entry
Spiketail Hatchling
I didn't forget about the Cosmos comparisons... I've just been a li'l disappointed in the new series and it's getting hard to hide. Today, I wanna talk about a few things:

A few months ago, I posted a long shebab about how to build Android apps from the command line. Just ignore it. Here's the dilly:

If you enter your Android application's base path and run "android create project", you can generate a source tree (with the res/ directory), a manifest file, and a base Activity. Running "android update project" can add libraries to your project's properties file. Running "ant debug" or "ant release" will build your APK file. It, of course, requires Apache Ant</i> as a build tool, but that actually comes with the Android SDK bundle, too.

I'm tired of writing code that just writes and parses save text... For
Pocket Starfighter, I just threw model data in-line with the algorithms. After hearing years of "model-view-controller" preaching, it was actually cool to have everything in-line. It sucks for scalability and adaptability. I created JFlagCap with the idea that I'd never grow tired of creating tilesets. Granted, for something that elaborate, something external was the only way to go. But, I'm unlikely to have folks clamoring to add flight models to Pocket Starfighter.

Anyway, this was restored from draft, so I have no idea where else it was going to go.
Apr. 6th, 2014 @ 11:16 pm Cosmos: A Spacetime Odyssey - Part 5
About this Entry
Spiketail Hatchling
As mentioned in the last review, the two series have gone completely apart from each other. Sagan's original series has Episode 5 as "Blues for a Red Planet". It tells a bunch of stories with red Mars at its center. We hear of H. G. Wells' War of the Worlds and Edgar Rice Burroughs' Barsoom series. In Sagan's characteristic way, he takes a pretty good amount of time out of his episode to take users to the 1800s with Percival Lowell and Robert Goddard.

It's obvious that Mars really captivated Sagan. His series features scale models that make Wells' Mars come alive with cities in spheres, canals, towers, and all the other trappings of the late 1800s-idealized-Mars. It really makes me wish Sagan had done some work in Sci-Fi.

The fifth episode of Tyson's series, though, was "Hiding in the Light"-- another evocative title. If my last review seemed a little negative, this episode makes things better. We learned how light works... and even poked around inside an atom (gosh-darn finally!). He goes on a rather long Islamic trip about what great scientists existed there, but, as usual, when folks discuss this part of the world, individual names are largely left out (with one exception), and things are discussed very, very broadly.

No pre-credits blurb. The show lacks consistency, but I feel like they're cutting out a lot of content for ads. In the show, after the Islam discussion (they should've mentioned the Baghdad Battery), we whiz past Newton and Hershel again in discussing optics and the way light works. He hinted at the Doppler effect and red-shifting of more distant galaxies... but, once again, he didn't cover it. He did discuss why we see color in a very visual way. Also, at the end, he showed what a cityscape looks like in various spectra. It would've been cool to know where the various spectra lie relative to each other, but I'm tired of having basic questions unanswered by the series... I'm guessing the idea here is that the watcher is supposed to be inspired to find this out on their own. Sagan's Cosmos gives a pretty good answer to most of my questions.

For an episode on color, the visuals are super top-notch. I think Annie was a little blase about this one, but to journey into an atom and see the orbitals was worth the mere 45 minutes of my time.

The new series is taking shape, though. It seems they watched the original series, dissected what elements are needed for an episode (visuals, biography, science, music, and emotional viscera) and went and dutifully put a little of each into these episodes. For this one (and episode 2), it worked... it really worked. Despite my petty whining, I found myself genuinely enjoying this one.

Unfortunately, I've been sick, so this post will be short. Next episode promises more waterbears!
Mar. 30th, 2014 @ 10:56 pm Cosmos: A Spacetime Odyssey - Part 4
About this Entry
Spiketail Hatchling
Jeez! Four episodes already. It's not really fair to compare the two Cosmoses together anymore since they've diverged pretty far from each other. Episode 4 of the original series ("Heaven and Hell") began by covering comets and asteroids, planetary moons, and cosmic disasters. It ended on a very sad note about how humankind is treating our Earth. It packed a lot of whallop with its usual 1980s bells and whistles.

Tyson's Cosmos dealt more with galaxies and black holes. The biography (if we can call it that) was for William Hershel, though he mentioned his son, and Einstein got his play. This is really closer to Epsiode VII in the original series ("Space and Time").

This said, looking forward, I really wish Tyson had spoken about how the nuclear furnace inside stars work. I wish he'd mentioned the Doppler effect the way Sagan did. By episode 4 in the series, Sagan had already taught us much about gravity, spectrometry, matter, and how things worked together, so the new series is really lagging behind. Tyson, this episode, got so close to talking about the four traditional forces of nature. It would've been the perfect opportunity. Since he's lagging behind, future episodes might have to get a little technically messy, or topics bluntly excluded... which is a shame. I don't want Cosmos to be just another science show.

Tyson wasn't all bad. He hinted at the relationship between space and time. This could've used some elaboration, though. While Sagan's gravity episode (coming in a future review) actually made sense, Tyson merely stated that gravity was a distortion of space-time. The things he did superbly was showing what would happen if we removed gravity, then if we increased it. It made a good segue to the black hole talk. Incidentally, he showed stars turning on from the condensation of interstellar gasses... which was pretty rad. He also showed us the most distant galaxy visible by radio telescopes and revisited the cosmic calendar. The best thing, though, was a brief recreation of the scene where he met Carl Sagan. It was pretty touching.

Another brief complaint about the new series— I realized watching "Heaven and Hell" that Carl Sagan is very particular about a sense of scale. I know I mentioned this before in regards to the Cosmic Calendar... but Sagan really points out the scale of things in a way that Tyson doesn't [yet].

This said, I still prefer the original series with its depth of coverage and how I walk away from it feeling like I understand more of the cosmos. It dawned on me today, also, that it had a more enjoyable soundtrack (for what it's worth). The new series seems a bit vacuous. Pretty pictures with no real lessons. I'm hoping that it gets better-- it already hints that it does.
Mar. 28th, 2014 @ 12:12 am Cosmos: A Spacetime Odyssey - Part 3
About this Entry
Spiketail Hatchling
I had an engagement on Sunday, so I missed watching the original Cosmos before the new one aired, but I caught up tonight, and, with the old Cosmos fresh in my head, I finally get to this.

So, the third episode is the first really biographical one. In Tyson's Cosmos, we're open with the credits screen— which is, I think, the first time the series does this. Both series attempt to explain the difference between scientific fact and faith, but the new series kinda falls short. By now, I grow a little weary of the animation (since it seems so rigid and-- I hate to say it-- lazy). Neil Tyson... he may be a great guy, a good father-figure, but he's no Sagan, and the series really suffers from his delivery and writing.

Perhaps it's because I just watched Carl and now my memory of Tyson is a little faded, but it's so inferior.

Presentation aside, the content is pretty good. He mentions Jan Oort, which I thought was pretty fantastic. While the original Cosmos begins with basic talks about astronomy vs. astrology. Carl makes a bunch of compelling arguments about why one is pretty much superior in every way, and how the other is inferior... in just about every way. He shows us (in that sorta National Geographic from the 1980s film style) worldwide ancient structures of astronomical importance. As I watched, I realized that this is probably the biggest differentiator between series: Carl goes for live-action reenactments, physical models, things that folks can see, mentally touch and imagine where Neil goes for flashier, more Hollywood kinds of awe. Both are aimed at invoking curiosity and a sense of awe, and maybe it's personal preference, but Carl stabs me in the heart every time.

After his basic introductions to astronomy, Carl follows the life of Kepler. He explains his life as a simple narrative, and thus chronologically explains the three laws of planetary motion, and the bumps that Kepler had on his way to discovery. Along the way, it introduces Tycho Brahe, a data collector of scientific importance. It also mentions the horrors that befell him and his family in the rough times of the 1600s.

The new series follows down the same path. It introduces Jan Oort, and, for once, the series doesn't portray him as a cartoon, but, rather a live-action dude standing in the Spaceship of the Imagination. I'd like to point out that Sagan's Cosmos had no Spaceship scenes in it this episode. That aside, Tyson's Cosmos introduces a few concepts in astronomy and astrology echoing in a few cases Sagan's own words and ideas.

Tyson's presentation follows a narrative of Robert Hooke, Edmond Halley, and Isaac Newton, focusing mainly on Halley. It hits on a bunch of events. Being familiar with the film Longitude, I was a pretty dag interested in this one. I was a little miffed by the animation, of course, but I liked their visual portrayal of Hooke. Also, Tyson's Cosmos introduces Kepler and briefly mentions the his first two laws-- but lacking the third, he didn't really hit Kepler home... which woulda been cool.

Anyway, the new series also briefly but interestingly covers how machines escape Earth's gravity. Also, it gets back to Halley's obsessive means of identifying and predicting the next coming of the comet that would bear his name. He further points out how mysticism could never give such a measurable, specific prediction. The series has some really whizz-bang graphics around comets. I really can't diss 'em. It's good.

The episode ends by sorta making its own little prediction about the merger of the Milky Way and Andromeda galaxies several billions of years from now. It was a pretty stunning simulation.

Anyway, I may have unfairly bashed the new Cosmos a little bit. I also, in reviewing this episode, realized that the original episodes on DVD (as I'm watching them) are a full hour where the new series have episodes close to 45 minutes. Despite any harshness, I'm already excited about the DVD release of this series.
Mar. 16th, 2014 @ 11:15 pm Cosmos: A Spacetime Odyssey - Part 2
About this Entry
Spiketail Hatchling
The series is starting to take shape as a sort of supplement to the original Cosmos.

Episode 2 of Cosmos: A Personal Voyage was the evolution episode about the origins of life and species titled "One Voice in the Cosmic Fugue". His introduction to artificial selection involved Heike crabs where those crabs whose carapace looked like that of a samurai were preferentially selected by humans since fishermen simply cast them back into the sea. Carl revisited the cosmic calendar from the previous episode and pointed out important dates in which evolution happened. He visited the Royal Conservatory and showed us step-by-step how humans evolved from one-celled organisms. This episode also went to Jupiter in the Ship of the Imagination and discussed life forms that might exist there, and it went into a single blood-cell of Sagan's and showed us DNA. The episode used Carl's slow pacing and had a lot of spirit.

Tyson's version is called "Some of the Things That Molecules Do"— a non-subtle hint at the source material. Near the end of the episode, footage from the original Cosmos was used and Carl's voice used those words. Neil used dogs as the example for how humans shaped the selection of species. Angie pointed out that his portrayal of wolves was wildly inaccurate and, in my ignorance of the subject (this is to say, as the oblivious "average viewer"), it got a bit of a shrug. He made his point. He went into a bear and showed the divergence between polar bears and brown bears. I felt a bit frustrated that he was somehow missing the true essence of the material, but I think that's just me. It was well-done. It was the animated portion of the show, since it seems that each show needs an animated bit.

Tyson also visited the tree of life, pointing out the abundance of species. He said a few wonderful things about how many species we still haven't classified and how for each living species there are many, many that have gone extinct. Unfortunately, he also showed a very pretty tree with some hard-to-make-out species tacked on. It was visually stunning, and really piqued my curiosity, but it didn't tell me anything. Carl Sagan drew a morphy line-image of a single celled organism and traced it through its path to becoming us. I was really hoping Tyson's Cosmos would do this. Infuriatingly, he replayed only forty-second spin-through of Sagan's evolution story (even billing it as "the greatest story science has ever told") with no context or narration. It was as though he said, "The original series did this, so we don't have to. Watch that for the whole story."

Not cool.

Interestingly, Sagan's series also visited Jupiter where Carl imagined what sort of creatures could live there. He gave three sturdy examples of organisms that made a sort of ecosystem. Spun together with some really rich paintings, it was the usual sort of fare that sent watchers day-dreaming.

Tyson's Cosmos went to Titan— a moon of Saturn— and poked a bit at the surface. It was made with a lot of flashy CG that really holds the series together. He mentioned that some life might exist, but it seemed like a teaser for a future episode. I felt a bit bummed by this.

Tyson's take on DNA was also a bit different. I appreciated seeing how it was formed, which was handled a bit more elegantly than the CG available in Sagan's epoch, but Sagan showed a model that showed that each nucleotide was made of atoms. It gave me a better idea of the nature of things. Tyson didn't use the word nucleotide, and, for all I knew, DNA was made of the wavy lightning of science fiction. I felt a bit insulted.

To Tyson's credit, though, he did show us some stuff that Sagan didn't. The stuff about Titan was really well-made visually. While Sagan had a cool clay-model of the Martian surface that he used a few times in his series, visuals here were really spectacular. Also, he visited the "Hall of Extinction". There were a few brief seconds that really captured the sadness of what we've lost by species dying. He also took us to one of the extinction events and, like Sagan, showed us trilobites. Also in this series was a brief segment on tardigrades, water bears, which Angie positively adored, and even impressed me.

But, once again, he peered down a hallway and said that one of the corridors wasn't ready for visiting yet... another promo for a future show. This bugged me again because this wasn't something the original series did at all. While it did revisit things, it never used things as a sales-pitch for the future.

So, the show is beginning to gain shortcomings when put side-by-side with the original series, but it's still immensely enjoyable.
Mar. 9th, 2014 @ 10:55 pm Cosmos: A Spacetime Odyssey - Part 1
About this Entry
Spiketail Hatchling
To the tune of: Vangelis
COSMOS! I've been so excited for this for the past month or so. Tonight, I watched Carl Sagan's Cosmos: A Personal Voyage before the big premiere so that I could do a little side-by-side.

Let me begin: this isn't a straightforward recap, but it does seem to be following the same general course. In the 1980 series, Carl Sagan started with a great big picture of the known universe and came to the Earth in the Spaceship of the Imagination. He introduced a lot of things slowly for an audience who may happened in on a lazy, Sunday afternoon. Carl has a very distinct voice that's slow but animated. His episode went on to the discovery of the diameter of the Earth around 500BC and explored the ancient library in Alexandria.

Neil DeGrasse Tyson's Cosmos begins from the inside and works its way out. He constructs humanity's address by visiting the Earth and the local solar system, then the galaxy as a whole, then the local group (briefly) before examining, quickly, the known universe. The pace is faster and the graphics are arguably better. His Ship of the Imagination is arguably better thought-out, but the pacing of the show doesn't give the audience time to really feel it. His pilot's main story is about the trial of Giordano Bruno— who Carl mentions later in his series— but this felt a little out of place for a pilot episode. It made me question the show's organization from the top-down.

Both series had a "cosmic calendar" sequence. The graphics were better, of course, in Tyson's Cosmos, but everything was portrayed slightly larger (the size of a living room vs. the size of a football field) in Sagan's. To Tyson's credit, he mentioned a few more dates that gave some interesting perspective to the age of the Milky Way, the sun, moon, and stars. We also got to see tiktaalik, which made my biologist-girlfriend quite pleased.

I read this article beforehand. The author says that Tyson reading from a script does him a real disservice. I tend to agree. Carl Sagan was the main writer for the original series, and when he spoke to the audience, it felt like he was sharing a story with us. Tyson, when he's on screen, carries the appropriate exuberance, but I found his narration a little cloying at other times. In his defense, he did have a rather touching tribute to Sagan at the end of the show.

I can't say definitively which series is better. Sagan and Tyson are different people. Sagan's series spent a lot of time and money hiring extras to portray people of historical importance where Tyson's opted for animators to help separate the past from the future. Sagan evoked the audience's imagination and put a heavy emphasis on the question of life elsewhere in the universe, where Tyson stuck to the facts and really tantalized viewers about things to come.

This didn't overwhelmingly blast me in the chest the way the original pilot did, but I'm really curious to see where the new series is going to go from here. Previews suggest it's going to follow Sagan's "One Voice in the Cosmic Fugue" where they discuss evolution. I'm still psyched.
Jan. 21st, 2014 @ 07:36 pm Numerical Evaluation
About this Entry
Spiketail Hatchling
To the tune of: http://celticradio.net/
In the past, I've written about making a mathematical calculator in Java using a JavaScript engine. Deep down, I've always wanted to write my own. I thought it would be all mathy, but, in truth, it's a whole bunch of teaching a computer algebra. As such, I have my own evaluator in Java! It's the heart of "Parametron" (links: here or here). Trick is to separate, evaluate recursively in order.

  public static double evaluate(String input) throws IllegalArgumentException {
                int i, j;
                //Log.i("***MARKDEBUG***", "Evaluating " + input  );

                // If it's a number, just return that number!
                // It's smart enough to handle negatives.
                try {
                        return Double.parseDouble(input);
                } catch ( Exception e ) { }

                // Named function!
                for ( i = 0; i < namedFunctions.length; i++ ) {
                        if ( input.indexOf(namedFunctions[i] + "(") >= 0 ) {
                                return doNamedFunction(input, namedFunctions[i]);
               // Find any other parentheses...
                i = input.indexOf("(");
                if ( i >= 0 ) {
                        j = findMatchingParen(input, i);
                        if ( j < 0 ) {
                                throw new IllegalArgumentException(input + " ...open '(' with no ')'.");
                        return evaluate(
                                        input.substring(0,i) +
                                        evaluate ( input.substring(i+1, j) ) +
                                        input.substring(j + 1, input.length())

                // FIND ADDITION!
                i = input.indexOf("+");
                if ( i > 0 )
                        return  evaluate(input.substring(0,i)) +
                                        evaluate( input.substring(i+1, input.length()) ); 

                // Find SUBTRACTION!
                for ( i = 0; i < input.length(); i++ ) {
                        if ( input.charAt(i) == '-' && i >= 1 && Character.isDigit( input.charAt(i - 1) ) )
                                return  evaluate(input.substring(0,i)) -
                                                evaluate( input.substring(i+1, input.length()) );
                        else if ( input.charAt(i) == '-' && i < input.length() - 1 &&
                                !Character.isDigit( input.charAt(i + 1) ) ) //UNARY MINUS (ACK! A HACK!)
                                return evaluate(input.substring(0,i) + "-1*" + input.substring(i+1, input.length()) );

                // Find DIVISION!
                i = input.indexOf("/");
                if ( i > 0 )
                        return  evaluate(input.substring(0,i)) /
                                evaluate( input.substring(i+1, input.length()) );

                // Find MULTIPLICATION!
                i = input.indexOf("*");
                if ( i > 0 )
               return  evaluate(input.substring(0,i)) *
                                evaluate( input.substring(i+1, input.length()) );

                // Find EXPONENTS! (Evaluated last)
                i = input.indexOf("^");
                if ( i > 0 )
                        return Math.pow(
                                evaluate( input.substring(i+1, input.length() )) );

                return 0;

I think it's pretty self-documenting in the Java kind of way. There are a coupla helper functions (findMatchingParen, doNamedFunction) which do exactly what you'd think. findMatchingParen takes a string and an index of a parenthesis. It iterates down the string incrementing some counter c when it encounters another opening parenthesis and decrements c on finding a closing one. When the counter is 0 (or wherever-it-started-minus-one), then that's the index that evaulate is looking for.

doNamedFunction does something only slightly more complicated than replacing a string like "cos" with a call to Math.cos(...).

Let me take a moment to discuss LISP. Seems a little out of the blue, but I've been doing pretty healthy amounts of fudging with Emacs Lisp as of late. It's got two things that make things easier: firstly, lambda expressions, and, secondly, a means to execute strings as part of a program. I understand that JavaScript borrowed both of these features... but let's look at how they'd apply to this numerical evaluator.

First and foremost, a user could type "cos(3.1415)" to get "-0.99996". In Java I had to parse out the string literal "cos" and call Double.parseDouble on the "3.1415" part. Then, conditionally, based on the function name, make a call to a Java function. In Lisp, I'd be able to transform "cos(3.1415)" to "(cos 3.1415)" then evaluate it with (eval (read-from-string "(cos 3.1415)" )) in Emacs Lisp it requires a call to car before read-from-string, but once again, it's a one-liner instead of an entire song-and-dance routine.

Speaking of which... wanna see how difficult it is to program a REPL in Common Lisp? Here: (do () (nil) (eval (read-from-string (read-line)))) In Emacs Lisp, the looping part is even nicer-looking and the program is generally more friendly: (while t (eval (car (read-from-string (read-from-minibuffer "> ")))))

Let's go back and talk about the first bit-- lambda expressions (λ!). It lets you pass functions around as parameters to other functions. In Java (or any organized, object-oriented language, but mainly java), each class is defined in its own file on the filesystem like Foo.java. If you have a bunch of public classes that are used everywhere, they need their own file. If you've got an interface, its methods have to be implemented in each file. This works.

But what if you've got a lot of implementors? Well, here's where OO-programming gets weak. I once wrote a little Nethack-ish game for homework in a programming course. It was a pain in the arse that each monster (inherits from Monster) had to have its own file when most of the things inside were basically the same. Integer for health, integers for possible damages and attacks, a couple of strings, etc. This could be realized in JSON much easier, but that requires even more Java overhead and it poses scope-problems... anyway, in Lisp, each monster type could be a line item in a list. Each instance could carry a copy of that list around, and special attacks (or other code hooks) could be mere elements of that list that defines the monster.

Anyway, download Parametron.
Oct. 28th, 2013 @ 11:26 am Quick One-Liner
About this Entry
Spiketail Hatchling
I know I don't post nearly as often as I should. Gotta work on that. Anyways, I've potentially got some excellent projects coming up including Nanowrimo later this week (in November). Really wanted to share this with everybody (especially myself in the future):

ping -o hostname | sed -n 's/.*bytes from \([^:]*\).*/\1/p'

That's right, kids: quick command-line means to extract only the IP address from a ping response given a hostname. Put that in your scripts and execute them.

'Til later.
Aug. 13th, 2013 @ 03:12 pm Android Development sans Eclipse
About this Entry
Spiketail Hatchling
When I started mobile development just over a year ago, iOS stuff was simple. There were iPhone and iPad apps and they were made in Xcode. At first, I had no idea where to go with Android and ended up generating a simple twelve-step procedure to get a sample app onto a device. Then, I discovered the ADT for Eclipse and that was that. That's the tools that all the developers are using. I became a pretty big fan. Eclipse is a really nifty tool with lots of good integration points with Android-- including some REALLY flashy memory and time profiling toys.

And then I'd use EMACS for everything else.

If you organize your project correctly (and don't mind doing edit-build-test cycles), one can easily cut out the eclipse piece from this equation.

Here are the rules (paths relative to a project's home directory):
  1. Source files in src/com/package/name
  2. Layout files in res/layout
  3. String values in res/values
  4. AndroidManifest.xml and build.sh goes in /
  5. dex files get generated into /build (so, remember to mkdir build)
  6. Copy requisite libraries to be somewhere that you'll remember.
  7. Always use a build script!

A build script-- build.sh-- is something easily generated. It does require a few steps, described in English here:

  1. aapt p -vfm -S res/ -J src/ -M AndroidManifest.xml -I /.../android-sdk/platforms/android-16/android.jar — We build the R.java file used in the source code to pull things from XML into Java.
  2. javac -classpath /.../android-sdk/platforms/android-16/android.jar:(other JARs here) src/org/package/name/* -d bin/ — Let's actually compile the .java files.
  3. dx --dex --output=build/classes.dex bin (other JARs' w/complete paths here) — Generate a .dex which is Android bytecode of your Java and XML goodies.
  4. aapt p -vf -M AndroidManifest.xml -S res/ -I /.../android-sdk/platforms/android-16/android.jar -F unsigned.apk build/ — Build the original, unsigned APK. This will need to be "signed" before it can run on a device...
  5. keytool -genkeypair -validity 10000 -dname "CN=company name" -keystore appname.keystore -keyalg RSA -alias someAlias — This doesn't need to be in your build.sh, but it does need to be run once per app to generate the .keystore file that signs the APK. The validity argument is in days-- for how long does your APK stay valid? You'll be prompted for a password. Make it obvious to yourself.
  6. jarsigner -verbose -keystore appname.keystore -signedjar signed.apk unsigned.apk someAlias — Crytograhically signs the APK, locking all its goodies inside in a basic attempt to prevent reverse engineering.

Then, to run the app programatically, here are these steps (for use with an emulator, replace -d with -e):
  1. adb -d uninstall org.package.name — Uninstall existing app.
  2. adb -d install signed.apk — Install the new app
  3. adb shell am start -n org.package.name/org.package.name.ActivityName — Launch the activity.

I'd recommend putting those in the same build script. Emacs has a pretty nice compile mode, so I have this in my .emacs file:

(global-set-key (kbd "") 'compile)

...so I can press F5 and run the build script.

Here's an example build script that uses Millennial Media's SDK as an external library (it's a stress test called 'CornerSim')...

mkdir build
aapt p -vfm -S res/ -J src/ -M AndroidManifest.xml -I ~/android-sdk/platforms/android-16/android.jar
javac -classpath /Users/mburger/android-sdk/platforms/android-16/android.jar:/Users/mburger/Downloads/MM-android-5.0.1/MMSDK.jar src/org/awesome/stress501/* -d bin/
dx --dex --output=build/classes.dex bin /Users/mburger/Downloads/MM-android-5.0.1/MMSDK.jar 
aapt p -vf -S res/ -M AndroidManifest.xml -I ~/android-sdk/platforms/android-16/android.jar -F unsigned.apk build/
jarsigner -verbose -keystore cornersim.keystore -signedjar signed.apk unsigned.apk cornersim
adb -d uninstall org.awesome.stress501
adb -d install signed.apk
adb shell am start -n org.awesome.stress501/org.awesome.stress501.Banner

...and that's that, friends. While I wrote this with EMACS in mind, it should free you up for vi, SAM, notepad, or even ed if you're so inclined.