I found the experience to be straightforward and intuitive. I was able to find tutorials for any task I couldn't figure out myself and the API documentation is perfectly adequate. Working with images and settings files are two areas where I was very pleasantly surprised at just how easy it was.
There were some minor frustrations. The Android emulator fought me a little so I started just debugging on my actual device. Debugging certain problems can be difficult, Eclipse can cause headaches and throw random nonexistent exceptions, etc. but overall I think you've vastly overstated the difficulty level of jumping into Android development. "The depth of knowledge of in design patterns required is so great..." It's really not. With almost no experience with Java or Android, I've put together a working app in a few days that, in my opinion at least, is pretty good, and that works on various mobile devices with different resolutions and capabilities.
Some other things I'm happy with about the Android platform: the SDK is free, Android is open source, you're very unrestricted with regards to what your app can do, and Android Market developer accounts cost a one time fee of $25 instead of $100 a year.
Every time I turned around, the Android platform surprised me. In a bad way. Full disclosure: I'm also not a Java fan, and think it was a completely brain-dead idea to make Java the first-class API. I'm certainly not a Microsoft fan, but even C#/Mono would have been better (not that I know any C#), if only so they wouldn't have had to waste time reimplementing the VM for licensing reasons. But it's not Java that I had a hard time with.
I've developed games on 12 different hardware/software platforms. There are so many things missing and/or broken about the way Android does things that I feel embarrassed for Google. Some of those things have subsequently been fixed, but many haven't, and some have been ignored in the bug database for YEARS now. A LOT of those things wouldn't have been problems if they didn't have so many layers between the app and the hardware (Java being one of those layers, but not the only problem).
As you say, it's really Not That Hard to just throw a simple app together that does what it needs to. Intents and Services are also ABSOLUTELY not the problem. The developer who wrote the original article didn't read enough of the docs or the right docs, or isn't as smart as he thinks he is -- the concept of Intents is not rocket science. The application lifecycle isn't even hard to understand -- it's laid out in the intro docs pretty clearly.
If only Android actually DID what those docs said, things would be a lot easier for a game developer. In fact, an "app" can be stopped and then a new one started before the old one actually receives its shut-down message. In the same (Linux) process -- so any native code with static data is still sitting around. One of many annoying problems I ran into.
I think the core mistake of almost every new platform is one of ego. "We'll design this NEW AND DIFFERENT platform in some revolutionary and awesome way, and make everyone rewrite their apps in this way feel is Better." When dealing with platforms, the one most important thing to do, in my opinion, is to HIDE the differences between one and another platform as much as possible. Android does this to some degree WITHIN the Android ecosystem, but we simply DON'T NEED multiple ecosystems. I submit it would be better for everyone if there were a single cross-platform engine that everyone used. Before I get dismissed as a kook, please think about OpenGL, and the fact that something as complex as a rendering subsystem IS in fact supported on all platforms, to everyone's benefit.
What would have been better is a library that abstracts away the fact that Android is its own unique OS, period. When I write code, I don't want it to be Android code, or iOS code, or WebOS code, or Windows [Mobile] code, or Linux code. I want it to be, as much as possible, completely cross-platform. I want the platform to fade into the background. You could bootstrap this by creating all the UI and other OS code as a portable layer that can run on many different systems.
But no new platform developer ever seems to get that, and so we end up with a new ecosystem for every new platform, and it's left to third parties to fill in the gap with cross-platform libraries. But it's not the developers -- or the users -- that big initiatives like Android get funded to satisfy.
/rant
I think everyone gets the value of cross-platform development, but in reality it's very difficult to achieve without enormous compromises and history tends to plot against it.
Apple's platform (Objective-C/Cocoa) can be traced back to NeXTstep. In 1988, it was the most progressive thing out there and some would say it still is. Apple leveraged their existing technology and ecosystem through OSX and all the way to iOS.
But the rest of the industry went in other directions. Objective-C/Cocoa would have been a strange choice for Android and would only have made it even more vulnerable to Apple's formidable patent arsenal. Instead, Android uses Java, which is also an attempt to leverage an existing ecosystem. But Android's fairly novel models of user interaction and application lifecycle required a whole new API. And Google had to reimplement the VM to avoid license fees, which still wasn't enough to avoid a patent attack.
In summary, as long as we have a) innovation and b) lawyers, we will constantly have to learn new development platforms which may not always be entirely novel.
>What would have been better is a library that abstracts away the fact that Android is its own unique OS, period. When I write code, I don't want it to be Android code, or iOS code, or WebOS code, or Windows [Mobile] code, or Linux code. ---
There are options out there. I'm one of those 3rd parties soon releasing a comprehensive middleware solution for app dev including a lot of game dev oriented effort that provides a clean abstraction layer via a component architecture that uses a large majority of advanced Java language features under the hood without sacrificing performance.
Keep a watch out for TyphonRT; drop me an email via the contact address and I'll be glad to discuss more and make sure you get early access. I'm aiming to get it out ASAP and before I give an all day game dev workshop at AnDevCon II in November. I suppose one thing that makes TyphonRT unique is that it's a tool, framework, and future platform (PaaS). At the heart of things you can pick and choose individual blocks of functionality (tool), or utilize the runtime framework (framework), and soon there will be optional PaaS features aiding Android and cross-platform dev in the coming year after launch.
Another Java based cross-platform effort which is similar in purpose though significantly different at the architecture level is libgdx. For C/C++ check out Battery Tech and the Proton SDK for similar cross-platform efforts (both of these with even more device coverage).
TyphonRT provides that layer of sugar you seek without losing performance and creating full cross-platform execution for OpenGL apps without changing a line of code for J2SE -> Android. TyphonRT is not limited to OpenGL though and can utilize any graphics API potentially allowing a hybrid UI, but the rest of an app still being cross-platform.
Having worked intensely with Android since v1.0 and the G1 hit my hands in Oct '08 I have more than a few stories on the difficulty of low level development / games, etc. across different OS and major device hardware generations. I've experienced first hand a good deal of general engineering blunders and have found and reported a few major ones myself (you know when big G fixes a bug immediately upon being reported you found a good one; the 3.0 & 3.1 / NIO immutable endian swap issue comes to mind!).
Middleware will mature and soon provide a lot that the Android SDK lacks for certain app development areas. In many ways the Android SDK while novel in several areas is still being developed from an old engineering model, but that is seemingly unavoidable for a large organization such as Google. There are of course additional inherent problems with tying the SDK to firmware, but such is life.
I do agree with your last point though that generally the SDK in addition to the particular ecosystem quirks that have occurred over time isn't exactly indicative of satisfying developers.
I got my apps ported and basic iOS/Android shells set up, and I haven't had to go back to the code for the OS-specific stuff in 6 months - all the continued development work has been in C++ at the GL ES level.
So, I would say, if you do your work properly you can set up a very comfortable environment, as a games programmer, to support cross-platform development on these platforms with ease.
I dont get your other complaints though. Show me a developer guide for a console platform that doesn't have outright lies in it and I'll show you my unicorn.
There is a single cross-platform engine, btw, its called Unity, and if you can live with its constraints, then off you go.
Its not in the platform creators best interest to make it compatible with other platforms. So dont hold your breath for write-once that doesnt suck.
EDIT: Disclosure - I am one of the rare types who is actually a big fan of both Java and Objective-C's syntax, though I'm more partial to Scala's approach than Java's, overall. I view Objective-C, conceptually, as somewhat in between C and Python, with good parts from both (though of course ObjC is far older)
Example #1:
I made the mistake of using ArrayAdapters, and hand-writing my own wrappers around the android sqlite libraries to manage my app's data. What did it get me? Garbage collection cycles that crashed the app, among other things.
Example #2:
I am of the opinion that in order to build a stable, robust app, Content Providers, at the very least, are required (for many reasons, the primary one currently being the ability to use LoaderManagers and CursorLoaders). But where was the documentation that explained why this was so? The complete lack of a centralized, high-level overview of Android systems have lead me to several development dead-ends, resulting in rewrites. While I'm wiser for the effort, and have finally settled on a sane, reusable, fairly general pattern for data-driven Android apps, I used up some really valuable development time finding this out. And you know what? Looking at the codebase before my (just-deployed) rewrite, and looking at the Android codebase at the job I left before it, everyone is making these same mistakes, and not many are realizing it until later.
Aside - Rant:
BaseColumns (http://developer.android.com/reference/android/provider/Base...) has no discernible use other than for a class to inherit some static variables. This is kind of ridiculous, as there's no requirement to use the column constants anyways, and they're static. I use enums instead, for each database table. Works much better. At my last job I even wrote an automatic SQL create statement generator for use in onUpgrade(). Oh, and if you want to use anything other than _id for the column name for your objects' unique IDs, you're not going to have an easy time with automatically binding your database objects to your UI.
Example #3:
Lots of stuff requires contexts. Against your common sense, you should try to avoid supplying the current activity as a context when you can use the application context instead. Why? Because if an Activity, which is a context, is retained as a member variable in something - perhaps a class that is, itself, a member variable of the aforementioned Activity, voila! You've got a circular reference and a potential memory leak! Where was this in the documentation? Nowhere. It was in a blog post that isn't exactly on most people's radar: http://android-developers.blogspot.com/2009/01/avoiding-memo...
Example #4:
Changing orientation destroys and recreates an Activity. Did a AsyncTask run at an inconvenient time? Oops. Chances are you're going to crash if you needed to do anything special with your Activity's state.
Example #5:
Using Apache's HTTP client? Careful. Don't use RequestWrapper, because executing a POST request wrapped in one can cause it to drop headers from the request. Just use different methods for HttpGet and HttpPost, and add on (for example) authentication parameters, device model names, other info for metrics, etc. separately for each. Funny thing is, I had better luck duplicating code for GET/POST here than reusing it, which I found disgusting, because duplicating code is not a good solution to anything, but it just got the work done.
Example #6:
I've gotten unreasonable Cursor closings that weren't my fault because someone at Motorola thought they were being clever and closing Cursors in a finalize() method was somehow a good idea: http://stackoverflow.com/questions/6552405/android-compatibi...
TL;DR (my main argument):
Android has many avoidable gotchas that require a solid programmer to identify and work around, but which aren't immediately fatal if ignored. Android provides a lot of infrastructure, and some of it is even good! Despite its mess of poorly-written, poorly-documented, or incorrect APIs, it manages to allow decent programmers to write pretty decent solutions and some pretty robust code. But it does a damn piss-poor job of documenting its wrongness when it rears its ugly head, and it fails to make clear that while there's freedom to do things many ways in Android, there are really only a few ways to do them well.
Rant #2:
All android devices seem to suffer from gross over-logging, some far more than others, like Motorola, or some newer HTC phones., which is a huge pain in the ass when I'm just concerned with my own error logs, and not spurious calls to the logger that the software author or device manufacturer forgot to or didn't care enough to elide.
Rant #3 (emphatically):
The worst and most fundamental flaw with it, though, IMO, is that the classes for the views and the serialization format representing them (the layout xml's) do not have anything even close to a 1:1 mapping. Serializing a class - it's not that hard. iOS does it by literally serializing the state of the view objects as configured in Interface Builder into what was once a binary file, but now is an XML file (nib, xib). Anything you can initialize or style or otherwise edit to affect the initial state of a view in interface builder or (were it reasonable) another method of directly editing the serialized representation you can also do in code. Not so in Android.
Here's a link to a post of mine last month that addresses some more gripes with Android: http://news.ycombinator.com/item?id=2737284
P.S. I've talked to Bob Lee (of Square; former core library lead of Android) about this before. Even he agreed that Android's APIs were poorly thought-out and designed in places. That's pretty damning right there.
Most of my iOS developer friends have no desire to learn Android. That is what makes Android development hot - as you have very little overlap of iOS and Android. Believe me, I've paid for attempting to switch back between iOS and Android with splitting headaches (if not done on separate days). I don't believe people who specialize in both.
You left something off your list, the sheer insanity of async loading images into a ListView. iOS developers have EGOImageView, we have a few competing implementations, including writing your own.
> I am of the opinion that in order to build a stable, robust app, Content Providers, at the very least, are required (for many reasons,
One way to see if someone knows what they are talking about is to ask them about multi-table content providers.
Also, what phone does the candidate have in his or her possession...
If the Android Market punishes people that do this then I think that's a very real problem with the market that will directly lead to poorer quality software.
Once you know Cocoa and Xcode iOS development is faster and more fun than Android development but it's no small learning curve. It's worth it for the fast turnaround of using the simulator compared to Android where both the emulator and device are slow, you're looking at 5-10x as long to launch your app compared to the iOS simulator. Plus ObjC > Java if you ask me, but I'm a masochist who likes both C and dynamic languages. Individual statements are verbose in Cocoa but I'd have to look at how much boilerplate is caused by the Java straight jacket to speculate on which is ultimately more verbose.
You also have to be willing to put with some crusty stuff. Nothing compared to OS X programming but it still feels old next to Java's APIs. Two good examples are string manipulation and interacting w/ the filesystem, so verbose on iOS but pretty good in Java.
I don't really have anything bad to say about WPF but when I first got my hands on UIKit and Objective-C I fell in love.
In WPF you can do anything and customize everything. UIKit is Apple's magical black box but it will get you like 80-90% of the way to your goal so you don't need to engineer everything like I did with WPF. Couple that with Foundation and their other great frameworks like CoreLocation and so much boilerplate code seems to be hidden behind Apple's walls.
I'm also probably in the minority but I like the verboseness of Objective-C and the dynamic nature of it. Honestly it is a small thing but not having to put null pointer checks all over my code is the thing about the language I love the most.
That said, the app I'm writing at work does a lot of stuff with strings, which you did mention specifically as a problem.
Properties also drive me crazy. just a ton of extra annoyance just to declare a variable.
I also prefer eclipse to xcode, and visual studio to both.
oh and good point about the simulator. The iOS simulators are MUCH better than the android simulator. So much faster.
iOS * AirPlay - My phone will be my gaming console and media center, genius! * iCloud - Good, no more transferring files back and forth. * CoreImage & AVFoundation - 30 lines of code to add video editing and filters to my application, sounds good! * GLKit - High-level 3D libraries for a game developer noob like me. I'm in! * TwitterAuth - I'm still going to integrate FB authentication but this is cool too.
Android * Ice Cream Sandwich - No more fragmentation. Unifies hundreds of devices (not just phones). Brand new UI library. I can't wait! * ADK - My home, car, and toaster will soon be at my mobile command while giving me status updates. This is so awesome! I foresee Android powered cleaning robots in the future. * Face-tracking - So my phone can recognize me and focus in on my face and voice automatically. This sounds like fun. * USB Host - I can plug anything USB into my Android phone. Hot damn!
This does not seem like a sustainable model. If my app and the next app a user launches are both memory heavy, I expect my app to be killed to make space. How does this process work on iOS?
Also, nobody really seems to understand how amazing Intents are before they use Android :)
I fought Android until I decided to throw my entire weight behind Java and settled on it as a platform. Don't fight it: learn Java proper, do a few SWT & Swing apps, feel the burn .. then do Android.
You can ignore the abstractions and just "draw up" your application with Eclipse, inside one giant activity, but you would be doing yourself a disservice.
I told myself "Java sucks, it's bloated, it's big, yada yada yada. Just man up and learn it; no sense in bitching about what you don't know" :-) Glad I did. It gets work done.
* A much more complex set of (good!) abstractions that are poorly documented;
* and, if I might add alongside the OP, requires a much higher workload in terms of code length and complexity, debugging, device configuration management and tools for what seems to be a much lower payoff?
I have a successful iOS app out, and I tried to rearchitect it in a manageable way to port it on Android. What I found out is:
* The code would be roughly twice as much as the iOS version.
* A proper UI effort would require roughly 2.5x work than the iOS version, as I need to prep up a flexible layout that will work on phones (the buckets 'small' to 'large'), and then another for tablets (actually up to two: 'xlarge' and Honeycomb, which may require some rethinking to accommodate the new action bar). Contrast this to two, fixed-size layouts for the iOS version.
* I already have a path for implementing backgrounding on iOS and it requires minimal change to account for services not available while backgrounded; otherwise, code is exactly the same. On Android, I would have to plan for it from the beginning and set up very poorly documented IBinder stuff to have my Activities talk to a background Service.
* The general unwillingness of Android users in the face of paid apps, and a use model that does not lend itself easily to the insertion of ads, would make my (more costly) effort go unpaid.
I must admit I have never used resources other than developer.android.com and Google, and the latter didn't help me as much as (as little as) developer.android.com did. There might be an excellent book on all of this, but I haven't bought any — any recommendations are welcome.
And you can try these sites for code snippets on anything:
Why would your app need twice as much code? Why is using the Android ui designer so much harder than iOS's equiv?
What is so undocumented about IBinder? It's basic IPC?
I would really like to hear reasons, not abbreviations.
An Android developer grows up once they have to deal with Activities going poof.
To be fair, services and content providers enable widgets. Widgets are a differentiator.
I also have to say that maybe iOS is bit easier to get started with but have the author come talk to me after doing ten or twenty apps wrangling core data, list view, sprites, physics engines, universal apps and mixing c c++ and objectice-c and tell me that rabbit hole is not pretty damn deep.
Gosling's "The Java Programming Language".
And Josh Bloch's "Effective Java".
After that, Java Concurrency in Practice.
Langr's "Agile Java" is good for just that.
Bloch, Goetz, and Doug Lea have each written excellent books on java concurrency.
That's just about all the java books I would want to recommend. Many j-books are trash.
I've been exploring iOS using Objective-C and I'm about half-way done with my first real app for the Appstore and I can't wait to try and rewrite it using ECL once it is done.
Otherwise it will probably be Unity for me since my main interest is games and game-like apps. I really don't have the time to become and expert in each and every differing mobile platform.
Our Android apps are all on the galaxy tablet, we plan to roll out a deployment of 50 devices by year's end.
Except... no, you don't. :/
The first sentence of the documentation on Service: "A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use."
Do you need to do either of those things? If you say no, then don't use Service.
http://developer.android.com/reference/android/app/Service.h...
In the Processes and Threads documentation: http://developer.android.com/guide/topics/fundamentals/proce...
It describes how when the user leaves the activity in a process, it goes in the background. It doesn't kill the process. You can continue doing networking. You don't need a Service to have background threads in your process. (In fact again from the Service documentation, a Service is not a thread at all.)
Just continue doing your work, and if the system needs your RAM for other processes, it will kill your process, but otherwise you can continue downloading in the background.
This is exactly how for example the web browser, and any app using a WebView, works.
This is similar in many ways to iOS. Not surprising, iOS seems um inspired in its multitasking design by Android.
He also failed to see the huge amount of community support there is for Android developers too. There's so much information inside multiple forums you would almost never be unable to find an answer to a problem.
The rest is/should be fair game. Try to run a hello world on the device.
I'm a Java developer and I don't know, either. I suspect the expertise you're looking for might be described as an "Android developer" ;)
Hey Google, Give us a nice scripting langauge. Pretty Please?
But one should remember that too high-level APIs and abstractions has its cost in terms of performance and bloatedness of required runtime (J2EE/Spring/Hibernate way) especially on resource-limited (lack of FPU, etc) platforms.
Well that's not true, the other thing I know for sure is Objective C makes me dry heave.
That's confusing to me. Message passing is one of the simplest actionable metaphors we have in the world of programming. I'm new to android development, but they seemed pretty straightforward to me.
Skillful Surround could be an attractive game if it got some TLC.
Building apps with JavaScript is doable, but has performance consequences that are severe on low-power mobile devices.
It's hard to fault Google for providing an open-source Java-compatible OS. It's not their fault if other OS builders are not compatible and actively block cross-platform solutions.
I haven't tried it, but I don't know a reason why one couldn't write an Android native app on Objective-C. You'd need a cross-compiler and technical/legal ability to port Cocoa though, the latter which I suspect would be quite challenging.
:)
I make iOS and Android applications for a living. It is ridiculous to have to create a service to make a few HTTP calls. For that, Android/Java provides various threading classes so that you can keep multi-threaded code nice and neat.
With iOS, out of the box, you get NSURL and its family. You have to setup callbacks in your class and you have to keep track of your http calls per class by using things like action=whatever. What a pain. ASIHTTPRequest makes things much easier.
Ugh, this just makes me mad. Why would people listen to shitty developers? Why are you spreading this ignorance?
Objective-C is a giant paint, with opaque types. Having to remember what class you've put into a dict can get messy.
I have to work with both frameworks every day, and Android is the better framework BY FAR.