Monday, December 27, 2010

Android vs. the Embedded Programmer Mindset

Eclipse Apps Roasting on an Open Android
ADB nipping at your serial bus.
Yuletide GUIs being compiled through XML,
And freakin' complicated data reference schemes that make you call even a single string from an outside standalone strings.xml file by @string/hello or R.string.hello.

Everybody knows a compiler and some global vars,
Help to make coding simple and fast.
Local functions with their scopes all aglo(bal).
Will find it much easier than dereferencing every gosh-darn string text variable.

What the helloworld, Google! Whatever happened to:

char gButtonText[] = "Option On";

function mytoggle( void) {
  strcpy(gButtonText,"Option Off")

Sure, it's ugly code. There's a better way to do it. But it's fast, easy, and simple, and intuitive to the C programmer's mindset. Welcome to the wonderful world of Java-inspired coding on Android. Everything is an object, and needs it's own varspace. Programming Android is like programming in Ruby on Rails' MVC stack. You aren't really writing a standalone app, you're just given the honor - and privilege if I say so - to glue on some function code on top of an existing framework. Programming Android is like programming Java - instead of thinking about building the app from the ground up, you're essentially writing a "diff" file on top of a massive mountain of existing code and functionality. The baseline app already does a bunch of stuff perfectly fine, thank you.

It's as if Android is constantly saying to me, "Oh, what, you want it to do something different? Overload my already perfectly-written function, why don't you. Pffft. I already thought of that. I have a better idea: why don't you *not* write your function, and instead use one of mine, and decrease the surplus population of crappy code!"

Bah humbugtracking
Programming in Android, like Java, I am constantly reminding of how little I know, because someone's already thought of that function, and it already exists - I just have to inherit and object and parent a class, @override a base class, and unprotect a final public method.

Want to make a toggle button change it's text? Duh:

android:textOff="Option Off"
android:textOn="Option On"

Herein lie the central difference in mindset between the Embedded Programmer and the Android Programmer:

Embedded (Arduino) Programming Mindset
In embedded land, we are trained to start from void main(void) and #include math.h and work upwards. From function control, application execution, to variable space definition, everything trains you to think about in a device-first mentality. You're thinking to yourself, "I have a device with XX megs of RAM, a YY MHz CPU, and a ZZ pixel screen." Optimization is the name of the game, efficiency matters, and resources are at a premium so it's worth taking the time to think them through.

Stretching the metaphor a bit for a minute, embedded coding is like heliocentrism - with the device at the center of the world:

Android Programming Mindset
In Android land, you are trained to start from a base, and extend some Activity class. You're writing diff code, pulling objects and their nested functions only when you need them. You are really writing *code*, you're just pulling and gluing together bits and pieces of functionality that were already written for you. The device doesn't matter, and why should it, because you're writing an app that might run on a tablet or a hand-held or an on-screen emulator. God only knows how many megs of RAM, CPU MHz, and pixels you'll have, so you'd better write your code abstractly and cross your fingers that it runs. Everything trains you to think about a user-first mentality.

All things considered, this isn't easy for an embedded programmer to embrace. Dare I say embracing and learning Android coding is the equivalent to the Copernican Revolution:

Device-first vs. User-first
Embedded programmers are more likely to build a new hardware device layer to push the performance envelope of a given piece of hardware. Android programmers are more likely to deliver a fantastic user experience that connects web-to-handheld-to-sensors first and foremost, and who cares if it sits and hangs for a few seconds while it calculates? The user will be stunned by the drop-shadowed jelly buttons, he won't even mind :-)

And the truth is... after several weeks of hacking my Android DIY Starter Kit, I don't mind either. I've found myself converting to a new religion, in the name of developing super-sleek looking GUI's in no time at all, it's really something. Doing the same in Linux would take weeks, maybe months (but that's another discussion for another time). Take my "void main( void)" from me, and give me my "public class extends Activity" any day of the week! But there are some downsides.

One major downside is the need for massively large reference manuals, or the need to constantly be connected to the web, for documentation, specs, and references. Try coding a rails webapp without access to the internet - impossible. On the other hand, all you need to code Arduino is a little cheatsheet - since you're essentially building everything up from scratch out of C primitive functions, all you need is the list of those functions. So what if you re-invent the wheel a few times? On Android, like Rails, you constantly need to know the top-down bigger picture. You need to have in your frame of mind the major high-level code objects, which you then reference down with the . dot-operator until you get to the method/function you were looking for. This means needing large amounts of documentation, and examples that are typically on the web.

Not better, not worse, mostly just different.


john personna said...

FWIW, I started GUI programming on the Mac, in 1984, in 68K asm. Bootstrapping on Android now, I find it very natural. It is both like the early Mac event model, and also leveraged on later generation OO advances.

I don't always like frameworks, but I think I like this one.

I'm not sure I totally get Activities and Intents yet, but it's certainly easy to build simple apps.

Anonymous said...

one other difference between bare bones and framework is that the framework people are trying to protect you from yourself. your initial c snippet has a buffer overflow :-)