"We often see questions from developers that are asking from the Android platform engineers about the kinds of design patterns and architectures they use in their apps. But the answer, maybe surprisingly, is we often don't have a strong opinion or really an opinion at all." (1)
While that may have been a lofty ideal, in practice Android has many strict requirements on how you partition your code between Activity, Fragment, ContentProvider, and Service classes. Never mind testability and all the new semi-opaque / intelligent battery optimizations Android applies to your app.
After all these years, I still find the most difficult and un-natural thing is mixing concurrency / background tasks that must outlive the UI with complex UI component lifecycles. This is a frequent and necessary thing to do, and also quite awkward. The result is unnecessary complexity that often and easily permeates the code. Dianne says they have no opinions on architecture, but where I disagree is concurrency is an architectural concern and there are definitely many corner cases & snafus mixing that with Android APIs.
Completely agree. I've been developing for Android since 1.0 and the complex interaction between background tasks and activity lifecycle is the worst part of Android that a significant majority of devs get wrong, introducing subtle bugs. (And the worst thing is that the documentation pretends like this issue doesn't exist last time I checked. Newbie developers have no chance getting this right, even experienced dev often ignore it.)
Overall, I wouldn't say Android is poorly designed, it's just mediocre, I would expect more from Google. In general, I'd say the design lacks simplicity and elegance. Some examples:
- Fragments. Activities were already overly complicated and for some mysterious reason they took it to the next level with fragments. (They should get rid of or redesigned activities too.)
- Older version of Google Cloud Messaging library - hundreds of lines of source code to implement a basic hello world example (wth)?
- Documentation is unclear in some cases, promoting some cargo cult patterns such view holders (zero effect on performence these days). Also, services, if you don't need IPC, the only "feature" of a service is that it lowers the probability that the app gets killed. I usually just create a simple service and start / stop it as a way to telling the system "don't kill the app".
I completely agree and although I only do it as a hobby, there are lots of points that many in the community feel as pain.
- They never managed to write a proper working emulator, while other companies had no problem doing so;
- The whole debacle of C++ support, had JetBrains not decided to create CLion, to this day Eclipse CDT would be deprecated without any official path for NDK users
- Speaking of NDK, the four parallel paths to build applications (old ndk-buld, experimental Gradle plugin, stable plugin with ndk-build, stable plugin with cmake), each with its own set of issues
- Dalvik JIT/GC were always worse than the average J2ME /J2Embedded commercial offerings, regardless of how they used to sell the story of having to fork Java for performance
- Choosing to AOT on device instead of doing at the store like everyone else, thus leading to the half-backed solution in Android 7 that everything goes (interpreter in Assembly, JIT with PGO, AOT when docked).
- Android Studio just puts my computer fans in full throttle bringing back memories from Webpshere RAD, something that Eclipse CDT never did. And I am not a big Eclipse fan.
- Gradle needs a background daemon with 2GB of allocated memory to match Ant or Maven performance
- The SupportLibrary releases that are so well tested that always required a minor updated, because they always break something
- I do approve that the NDK is constrained due to security concerns, but being forced to use JNI to call libraries that are implemented in C++ like Skia?
- Forking Java community with cherry picked features from Java 6, 7 and 8. Which will only get worse now that Java 9 and 10 will bring features that will drastically change how the language is used (modules, linker, graal, value types, type inference,....).
There are plenty of other issues to rant about, these are just some of them.
They seem to just keep Android on some kind of "just good enough" for the masses. Literally the MS-DOS of mobile world.
Android exists to collect data and serves as an ad platform. iOS exists to sell hardware.
The quality of the dev tools and on-boarding reflects that.
At the end of the day, dear Google is (now) still just a marketing company, however well they may treat the intellect they are hoarding.
Yes, I'm ignoring that Google was founded on some really awesome technological ideas, or at least a very clever assemblage thereof, but monetizing those ideas required becoming a marketing company. Preserving their value means extending that core business throughout what they do.
That said, our personal phone gear at home is Android, cuz I'm cheap. BUT, I'm really getting fed up with all of the damn notices that literally cause my phone to beep several times an hour for nothing. I love my iPad mini - not only can it do web, email and MP3s, it also makes a pretty good (MIDI) synthesizer :-)
There's a few major problems with doing it at the store.
1: Google can only AOT for their devices as the AOT depends upon the specific platform version that the app will be installed on (as symbols & offsets change, of course). It's a substantial scalability problem.
2: The compiled version is substantially larger than the dex code. That's a non-trivial cost (in terms of $$$) to put on people in the majority of the world that doesn't have high caps and/or unlimited bandwidth.
3: Apps are signed by the developer, so the store can't recompile the app without breaking the certificate chain. And then the app won't be able to update anymore, and the trust flow back to the original developer is lost.
That can also build NDK and Android.
Time to bypass Google and just use plain old cmake instead. So far, it is still possible to just run java+dex or jack straight from command line...
It's how we support cross-platform C++ libraries.
That's the reason I'm not using my Nexus 10 tablet anymore. So, it doesn't only hurt the developers, but users as well.
I think it is mostly have to do with company's talent pool and focus.
As far as I can see (I may be wrong, this is my estimate) Google tries hard to devote best talents to 1) ads and Search and it's maintaining 2) Chrome team 3) Google apps and services online and on iPhones.
After these option they try to develop Android as kinda (I don't know what is they correct word, so I am going with kinda) side project because they know the world needs an open platform for competing with apples devices.
The reason because why Android is unacceptable from Google is we all used Google's best products. Chrome and search and we kinda (by default) think about Google as non fallible.
But that's nowhere near the reality, they have limited number of super smart guys, and they try their best to keep core products (search and browser) much better than competitors.
Most of the time when Google does release a new app their iOS apps is better than Android's ones.
We would be okay if Android was from mediocre company. But it is not, it is from Google , which is the best in some areas. But they don't have unlimited talent. They are trying their best to balance.
I am not saying people who worked on Android are not that bright. No I am talking about more broader picture. Of course there some excellent people who work on Android. But I am not talking about 1,2 or three. I am talking about management perspective in broader sense.
This is my personal understanding, I may be completely wrong.
Look at Google's efforts on web frontend - GWT, Polymer, Angular 1/2, embracing TypeScript, RxJS, and so on. In other words, they've devoted significant resources to high-level application patterns, emerging paradigms, and in general - improving developer experience. The Chrome devtools are another example.
On Android, not only is their policy to "remain neutral" on architecture and paradigms, but they don't even bother to update the platform enough to let the community take on the architectural work. The tooling is 1 step forward 2 steps back, new language features (or languages!) do not seem to be a priority, fixing fundamental design errors (multidex) is also not a priority, things like databinding are trotted out and then stagnate, and so on.
The only conclusion I'm left to draw is that Android is the new Windows. Why should Google care about developer experience on Android when it owns 70% of the market.
There seems to have been something of a civil war right around the launch of Android Honeycomb/3.0, as that was also when Chromebooks happened.
All of a sudden you had two platforms, both angling for "landscape" devices.
I seem to recall that he was the one that insisted that Android was for phones, and thus devices without a mobile radio was unable to get a CDD certification.
I don't know where you would insert WebApps in this list but it looks like that they are taking bigger portions of the Google Keynotes lately. Seems that Google is pursuing to arrive quick to the point where WebApps can substitute native apps. You can skip app stores (manifest), run apps in the background, synchronize and receive push notifications (service workers). They have dedicated talented people to design the specs (like Jake Archivald) and they are early adopters of them (Chrome and Android).
WebApps are probably the greater threat to native apps. Apple resists hard to them (imagine the profit loss if anyone can bypass the App Store and it's commission e.g. Amazon).
Webapps can't be used for high performance applications like games, music or VR. But definitely can make that talent or atention to be taken from the native ones.
There is so much articles and news about it. It is completely rational decision. Google like any other company at the end wants to maximize its profit, and iPhone is where the money is (Google it, 84% of profit of whole market goes to apples pocket_ I don't remember exact number).
I have used HTC desire around 2011 (I don't remember the exact model name) and my gf was using Samsung note (around the same time) the experience was disaster, no updates, bloated software, no bug fix, nos security fixes. Nothing,pure marketing and pure rip off. After a year I switched to Nexus line and my gf using iPhone. We haven't thought about buying anything else since then.
And right now , with this update problem Google imposing on Nexus line, my last hope for Android is dieing and I am considering buying iPhone. I switched from Nexus 4 to Nexus 5. It is unacceptable to me, device as capable as Nexus 5 doesnt get N update. Why would I use Android when I have better support, long term update with iPhone almost for same price (I could have bought iPhone 5 for 100$ 150$ more when I bought Nexus 5. Which was total mistake)
And remember developing for Android is what I do for living. So I am so enthusiastic about androids future.
I have really high hopes for Windows 10 phone. Their continum can be game changer. And don't forget Google is not software company, they are IT company. But Microsoft is different, they are biggest most successful software company in humankind history. They know how to develop software. The problem with their failure was stupid manager (Steve ballmer). Which is now solved. I hope they can compete with iPhone with their surface phone line. We will see how it is going to pan out.
Apple doesn't need to standardise. They can get away with just supporting their own devices.
Even with standardization, hardware differences will necessitate testing on older devices. That does not come for free for the manufacturers, and it has been, and is seen as, an entirely avoidable and unnecessary expense (which is one big reason they don't provide updates for a longer duration right now). Are the majority of customers even capable of dealing with rooting the phone or flashing it with some un-tested firmware? The phone makers and customers are used to not having updates for a long time, and neither of them really care (if you look at the majority non-tech crowd). Why or how would all these other dynamics change just because SoCs get standardized (if that happens)?
On top of that Google could implement a standardized UI themeing system, allowing companies to give their products a distinct experience without having to muck with the code as much.
It may not be their fault, but it is their problem. This is a huge problem for Android as a platform.
Their entire purpose is to use technology to manage information. What does "IT" stand for again?
By the way, I think Android UI works much better than iOS's.
You should be specific about what about Android UI is better than iOS?
if you are saying android UI design is better than iOS , I agree , but remember Material design is not android's design. Google wants to expend to every platform, it is quite childish if we think they could expand to every platform without having professional UI design language for themselves. They designed Material design for all of their product, not just for android. Yes android was first one to adopt, and I really like Material design. So if you are talking about material design , it was not only for android, it was actually Google Design language, and I really like it.
But if you are talking about performance and how ui fits together, I disagree 100% , for example they didn't had splashscreen for long long time (If I remember correctly they adopt splash screen a year o two ago), every time you were going to open an app, you were noticing a blank screen for quite a long time some times(1,2 second) which was quite ridiculous. At the other hand iOS had fixed splash screen for quite long time. Some third party apps tried to develop splash screen of their own , but almost all the time result was not on par (not even close) with iOS counterparts.
Right now their rotation animation have problems which can show itself under pressure. and so many thing I don't even remember right now.
I am not saying android is bad or something , android is wonderful product. But lets be honest, it is not core product for Google like chrome is, and it has huge problems. But its main advantage is its openness.
One of big Android advantages are activities and intents. It allows for application cooperation in a way that's not possible on iPhone. Even the default app concept is based on intent handling - and that's why I can use Firefox as my default browser, Nine as my default mail app and Sygic as my default navigation and send stuff from other apps over Threema. On iPhone, I would be stuck with Safari/Apple mail/Apple maps/iMessage no matter what others offer.
This also affects integration from third parties. There's no reason for an app to support just Dropbox, when there are intents, that all other services support. Unless you want to artificially limit the integration, or you came from iOS and are not used to that.
Aka as Metro design language actually.
It's good, because it doesn't require you to use the workaround of deluding the user with a SCREENSHOT of your layout (sic; see the accepted answer above).
As an Android dev I'm in the camp that steers clear of Fragments out of principle, if only possible.
Only use them in a single form. FragmentTransaction add/remove/replace, no fragment tags in xml to cause inconsistent behavior
Represent state with single AutoValue + Auto Parcel object and save it with Icepick so they work with process death automatically
Implement all interactions with other threads via RxJava so I can unsubscribe and avoid "after onInstanceState exceptions"
Use custom view groups instead of nested fragments since nested fragments tend to not be using the backstack anyways
The basic concept behind Fragments was pretty much the same as WebOS' Enyo framework. I recall one of the big Enyo demo moments was when a browser window was resized, and the email app ui went from multiple columns to a single column, and back, without missing a beat.
Then again i wonder if Android was partially designed, before Fragments, to rekindle the experience of using Apple's Newton tablet. This in that one app would extend the functionality of another app in a virtually seamless manner via intents.
But as best i can tell, Android left too much of the plumbing in the hands of the app devs. Thus for every app that handled cross-app intents properly, you got 100+ that would jump back through the in-app activity history rather than roll back the intent chain.
And with fragments you got a in-app way to do the activity history backtracking, while still having the intent focused back button of the Android UI.
Android is just one of those Big Corp projects were you hastily throw enough shit at the wall and see what sticks. It wasn't "designed", it's just the way it came out.
Same problem goes for not understanding detachable threads in other languages (eg. keeping a reference/pointer to them and attempting to use them when you have no idea when they've finished) but that's a newbie problem. I wouldn't say that the language or design of threads was at fault if I was using it wrong.
They are in the same process, you can communicate between them through all the normal Java mechanisms. For example, your UI can just register & unregister a callback on the service directly in its start/stop methods (or in onVisibilityChanged if you'd rather do this in a View instead)
The trick with Android-development really is to acknowledge that large parts of the SDK are just crap and that you are better served writing custom code than trying to use it.
Also, I'm currently using this technique with Xamarin, which opens up some techniques that would be hard to pull off with native. So in this case I use an Angular-style MVVM pattern, so the custom views are all bound to corresponding viewmodels. So the custom views all share one small piece of code that takes care of some binding-related plumbing, and otherwise they're nothing but AXML with binding statements in it. This adds up to a rather pleasing approximation of a web-frontend-style component-based architecture. Xamarin should really be more popular!
this is being fixed. The problem is that this is political as well as technical. The solution went from GCMNetworkManager to JobScheduler to the now recommended Firebase Jobdispatcher (https://developer.android.com/topic/performance/scheduling.h...).
P.S. Firebase was a newly acquired startup at Google.
Firebase Jobdispatcher should be able to take care of your concurrency issues in a power efficient way.
This and the weaknesses of AsyncTask are the reason why RxJava has been adopted so quickly on the Android side. Event buses are dead or dying.
With that said, Rx is still a moving target and it seems to attract a proliferation of redundant, but slightly different, operators that scare away newbies. Observables, schedulers, and map/flatMap/filter are immensely useful to any old school Android developer.
Most of the responses Ive gotten from coworkers is "what would you change". I have a hard time answering that.
Device/OS proliferation has made android dev pretty complicated these days.
I think some things like replacing bitfields with Enums could maybe be done transparently with a little ART modification.
The most useful things you can do for yourself currently are:
* Adopt Kotlin as a language. It's not all that different from Swift, comes with IDE support, tiny standard library and really fixes the pain of Java 6.
* Use MVP patterns and its friends. There are a few libraries which take most of the pain of lifecycles away.
* Use RxJava, Retrofit, Glide, etc. libraries that make your life easier with concurrency. A lot of these tools are better and easier to use than what even exists on iOS. Using AsyncTask in 2016 is just silly, it was never a good API.
* Use Gradle! Driven by its scripting language, you can do so much to script and automatize your build.
Other than that, I agree, after years of development:
* Some Android APIs just aren't well thought out.
* Gradle badly needs performance improvement.
* State of NDK is just sad. Fixable, but sad.
* MultiDEX is a result of a very very dumb decision in Android 1.0 and it's going to hurt us for a long time :/
(And no I'm not saying Android is great or even a great platform. It's not. It's just that, just like on Web, you can do a lot to fix major pains.)
It's just a mess. I'd expect a relatively painless experience: install dev tools, start a new project, build and go! But no, it's jumping through hoops, requires understanding a myriad of different SDK/platform versions and a constant churn in keeping your apps up to date with new versions while trying not to break backwards compatibility.
And a big part of this mess comes from the fact that device manufacturers and mobile operators are unwilling to keep old devices up to date (and Google can't force them, while I think they should with some kind of licensing contracts), leaving customers exposed to security flaws while keeping the developers churn high with multiple versions to be supported.
I also have no idea why are you mixing the device updates into the developer tooling argument. New apps are (should be - and the tutorials tell you so) developed with API 19+ in mind which means that you'll have to work for quite a while to get any problems with fragmentation and updates. You can even start development on API 21 and ditch support libraries all together and STILL not shed significant amount of userbase.
I tried this after their 1.0 release and it crashed. Mileage varies from person to person
I agree it was abysmal at first - when it didn't crash, every new update would break compatibility and your projects wouldn't build anymore etc.
Right now it's pretty decent, considering, although I'm not a fan of Gradle either.
By the way, even though it's a fork of IntelliJ Idea, it's ultimately shaped by Google which has sort of a tradition of realeasing alpha-stage software into the world. Remember first releases of Chrome? I do; they crashed like crazy and lacked basic functionality such as printing.
> And a big part of this mess comes from the fact that device manufacturers and mobile operators are unwilling to keep old devices up to date (and Google can't force them, while I think they should with some kind of licensing contracts), leaving customers exposed to security flaws while keeping the developers churn high with multiple versions to be supported.
Is it only me or there are tons of similarities to C# and the .Net environment?! More and more I feel Google just ends up with the same solution MS came up with in order to handle the diversity of vendors using its platform and their conflicting interesse.
(That said, I'm very glad that this is the top-voted comment, since it looks like a very valuable resource for lurkers who want to get into the topic.)
The only exception is Kotlin as a language, which is pretty new and the tooling is still improving. You're not going to hurt TOO much if you stay with Java6 though.
Remember, we at the end of the day we're all just old Java farts and we like our stability ;)
Which speaks a lot about the quality of work provided by the platform owner, when the community needs to step up.
I mean, yeah, in perfect world we'd all have neatly packaged by Google, we'd write 6 lines of code and have the greatest app ever. But software development never kinda worked that way for me and I have a feeling it never will :/
Python's biggest strength that lead to its adoption was being a language with "Batteries Included".
I am also thinking about learning Android development and don't really know where to begin.
So everyone suffers when anything more complex than hello world already required third party libraries, specially ones that aren't even acknowledged by Google.
Also the Android operating system isn't a language.
If a company wants to vet all of their software, good on them! But that doesn't mean that anything that's not vetted by them is somehow worse for the majority of users, just that they haven't vetted it yet. So any arguments about how "library x" isn't usable by them won't apply to the vast majority of people, because most don't have that issue, or have no problems vetting that library as well.
Somewhat off topic. Is there a word that encompses the langauge, platform, runtime, etc...? I hate the word "ecosystem", but it seems like the best bet. And using any one of the others brings out comments of "well it's not a language" or "it's not a framework it's a library" or something else.
If you assume a roughly logarithmic intersection of shared dependencies that's O(N^2 log n) chances for a bug. But in some communities I'm sure even that is optimistic.
When you have a more complicated project it's fine to rely on repo packages (Python does as well for eg. web frameworks like Django aren't in the core). In fact python std lib is hugely inconsistent stylistically as a result of needing to keep it stable over the releases as people expect it to be backcompatible and package versions are tied to language versions. If it had proper versioned dependencies doing breaking refactoring over the years would be really easy and non-intrusive.
Apple didn't come up with dependency/package managers like Carthage or Cocoapods, the community did. There's just enormous amounts of OSS libraries provided by the community too, with ones like Alamofire smoothing out the rough edges of iOS's networking APIs.
I have multiple personal Obj-C/Swift projects on iOS and macOS that don't use any kind of dependency management and use very few third party libraries and working on them has never been an issue or source of pain.
Thats not a bragging point.
Rememember that Google has been advocating AsyncTask in the past. You could use something else or roll your own, but it doesn't make sense to do that when AsyncTask is being communicated as the way forward. They should've embraced third-party libraries, but instead they still communicate how to use AsyncTask. Example: last March 2016 they published a video on how to use AsyncTask . They do highlight the red-flags around it, but do not mention any of the third-party libraries that are considered standard for a lot of Android developers already.
The same goes for Fragments. It is still being advocated as the right way, but I have some doubts. I imagine they will be advocated against in a couple of years. They help at the time, but are far from logical/simple when you don't know all of the crooks and crannies (and there are quite a few).
Another API that needs serious work is the Storage Access Framework (SAF). Previously Android applications could use the Java File API to access files. With recent Android versions this has been closed off with good reasons and intentions. Instead of using the File API directly, you now need to use SAF. SAF doesn't support all operations you could do with the File API. I would say this is a regression and existing applications that relied on these features are now broken and unrepairable. In addition, applications now needed to explicitly ask the user for permission to specific directories or files. This was so badly implemented that every file manager needed to instruct the user on how to use the directory picker of Android using screenshots before showing the picker. This is still a problem and even if it is fixed, it will still be a problem for years due to phones being unable to update.
To give you an impression on how those APIs are designed: many calls of SAF will return null to indicate something went wrong. No exceptions or error-codes. There is often no indication why a certain file cannot be retrieved. It could be non-existing, it could be denied permissions, it could be some strange behavior in the rom. There is sometimes a way to find out why this returned null and that is looking through Androids global log. I've implemented this in the beta of my app so that I could find out why files weren't accessible on some devices.
Also, because of the slow adoption of Android versions, your application needs to support both SAF and the Java File API. The support library has wrappers for Java File API that works like SAF, but it's still a downgrade to use this API as exceptions from the Java File API are just ignored .
For me Gradle is actually a step in the right direction. Builds seem to be more reproducible and do not fail randomly compared to the Eclipse/Ant days. The performance is however awful. Incremental builds take 30 - 60 seconds. When comparing this to building pure Java projects it shows that it is an Android-only issue and not one with Gradle.
The author states pretty plainly the biggest reason for leaving Android development was he didn't have time to keep up with all the developments in both Android and iOS communities.
Multidex ? it is far from perfect but it is not a day to day issue. I work on a 200k methods app and multidex actually makes it almost entirely painless.
Gradle ? Nobody can seriously say that builds have gotten worse with gradle. Before it, we had no way to hook up libraries with resources (aar). Now we just have to 'import libname:version'
The complaint on the build times is very fair though. The solution is easy though .. just use an high end computer
I use a mid 2015 mbp, it can handle an huge android app without any issue (except that build times are only acceptable, not great).
It really looks like he has been submerged with having 2 platforms to learn at once and has not been able to tackle the basics.
For kotlin, no book needed.
Go to the language website, read the introduction, maybe a couple of pages on the language features and then complete the kotlin koans. It will give you an overview of most of the language features.
After that, find an android project written in kotlin.
Here is one : https://github.com/LostInContext/LostContext-App (there are many others) .
Configuring an android project in kotlin the first time can be painful, especially if you have some code generation (dagger, databinding, ...) , so it is way easier to have a working sample to work with.
Cost benefit also is probably lot better on the iOS side ($$$ you get to develop an app / time to develop it).
gradle --daemon is a hack, I guess, but I always use it for my builds (even aliased gradle to gradle --daemon). It's far too slow otherwise.
On newer gradle releases I believe the daemon is enabled by default.
Incidentally, our Kotlin-based app actually has a completely custom one that an opinionated product guy wrote that works reasonably well, but it still needs a lot of work and probably to be fully extracted for an OSS release. We also have some Kotlin delegated properties and other magic for cutting down on lifecycle & state management boilerplate.
I think that's kind of his point. He was spreads too thin.
* and its management
* by its scripting language
I'm not saying that iOS is better. Don't really know. I've played with Swift and a few of the Apple tutorials.
In general, I'm against the current incarnation of mobile. After years of having an Android (and now having an iPhone due to work), I switched to a Samsung Juke. That's right, a feature phone! The Android just got slower and slower. No updates, not improvements. Finally it screeched in my ears while working. I picked it up and slammed it on the desk (felt great for a week). Both iOS and Android are slow, overly wrought operating systems.
That being said, unlike the author, I'll still use Android and iOS for my products. I have products that need to be mobile. They have to target the machines my customers have now. That also means that I'll have two native app code bases. I'll have to keep track of native app UX/UI standards. I'll have to keep such hardware around ('cause Android's emulator is still sucks when I've got an VM running).
Google's user faced architecture often just seems like an unmanaged jumbled up bunch of code that they throw at you, good luck have fun.
That's a little bit like saying that Chez Panisse doesn't even deliver sewage to your table, and that if you want to pour it over your food you need to bring your own chamber pot with you.
But I've found some peace using Android without the mothership. That's CopperheadOS with F-droid:
It's simple and it works well.
But yeah, things are a bit messy from a development perspective. Too much fragmentation I guess.
Basically pair featurephone with smartphone or tablet, and then tell the smartphone or tablet to use the featurephone as their internet connection.
Mind you this is all on Android, and i am not American so i do not have to deal with carriers mucking up my featurephone firmware.
Edit: Just reminded myself that the term used is tethering. If i can't find a wifi hotspot to use, i tether smart device to the featurephone over bluetooth and thus use the phones mobile connection as the net connection for the smart device.
I wish the big 4 would get their act together and stop pissing on each others legs.
FB is the most recent entry into this clusterfuck. They should be ashamed of the Oculus/GearVR developer experience, it was the determining factor in my abandoning Oculus.
It is the developer that pays the cost in the end.
Yep and I think too many have that same feeling. Not sure if they can afford that but we will see.
I consider myself an expert in Android development. The only point that I agree with is multidex, but there are historical reasons for the limitation and I think Google engineers are trying to fix this problem or make it as simple as possible to use multidex.
I occasionally do iOS development and some things in iOS don't make sense to me, but I'm sure they would be obvious for an iOS expert.
My advice for mobile developers or future mobile developers is to specialize in a single platform that you like more. For me it's Android. For the author of the article, it seems to be iOS.
I would say what most annoys me about iOS is the GPL thing which is the reason, among others, there are no emulators in the Appstore, at least no relevant ones. As owner of a museum and fan of old machines I cannot do without emulators. On my Android tablet I have around 50. Emulators is a niche but no GPL is hampering a lot for everyone on iOS.
But yes the other restriction sucks too. The point was cannot normally use emulators under iOS which stands, whatever the reason may be.
Employers need to wisen up and not expect mobile developers to be masters across these dual platforms. Plumbers don't do electrical work, paramedics don't chase criminals. I like to browse iOS/Android mobile dev job descriptions for fun, and I grit my teeth when it is expected that you be a master at both. Not a chance, everything moves too fast.
I have also been offered a couple of iOS jobs (from companies wishing to hire me but not currently hiring for Android).
Finally out of our 15 android devs, 2 of them are also iOS devs (and work for us on both platforms).
They quite proficient with both platforms (well, Android anyway but I heard no complaints from the iOS team). Sure, they are not as proficient as our best Android engineers, but they are still pulling their weight.
Maybe the difference is that we are not an agency but a mobile team working on a single app.
We can take the time to learn the platform and teach to our colleagues. Maybe that a freelancer does not have this luxury or the adequate structure.
The only thing worse than gradle is ANT, which it replaced.
> Wait, what is picasso? Oh wow, I hadn’t heard of that one…I was busy learning Swift.
I just minimize the amount of platform specific tech in the codebase as much as possible. RxJava? That's going to be real fun to port...
Ahh, this didn't even touch on my least favorite part of Android - command line tools that tell you they've "successfully" deployed APKs. And returned successful return codes. That in reality silently failed due to ever so slightly loose USB connections.
On the plus side, they finally fixed https://code.google.com/p/android/issues/detail?id=197287 in Android 7.0 it looks like...? I'm trying to remember if that was the bug to blame for my last 16 hour day...
However Android has come a long way since the early days. The author focuses on the bad things we all know about. Android development is incrementally getting better every month.
On top of that Android Studio is a way better development tool than Xcode. To the point that I wish Apple drops Xcode completely and starts using AppCode.
- Android Studio has powerful refactoring tools. Xcode lets you do some basic refactoring only on Objective C
- Despite gradle being a pain, it gives you dependency management. To get that on iOS you have to resort to third party tools like cocoapods or carthage (though swift has now one too)
- Autocomplete works reliably, every single time
- Translations are way easier to do. Android studio comes with a translation editor and translations are in one place. I welcome you to try to translate a storyboard on Xcode and maintain that.
- Android Studio UI editor is now way better than what it used to be. Despite that, Interface Builder is still the king of UI editors.
- Editing the UI XML is trivial on Android. Try to merge a storyboard or a xib... and Android Studio does not automatically modify your UI xml files every time you open them.
- Signing on Android is a thing you configure once and that's it. I have wasted days dealing with signing problems on iOS.
However I enjoy more doing iOS development. I cannot explain why, it is a more pleasant experience. At least to me.
I still love both platforms anyway.
Gradle will never be a fast build tool due to its design goals. It was a clear mistake to switch to them if you applied any knowledge of build tools.
Google suggestions to ease the problems are to have a background daemon, using a JVM with at least 2GB allocated to it.
Ant and Maven don't require any of this stuff to perform fast builds.
What's wrong with ant? I liked it.. It was simple to understand for the most part.
It also made it easy to develop without an IDE, although I'll admit I don't know how easy it is now as I stopped doing Android a year ago
It's also slow as arse unfortunately.
I appreciate the reply
With Android, they seemed to change the build files every minor release (my info may be out of date here).
Dependencies were a mess. Depend on A and B with both depend on C? C gets pulled in twice, build fails. Workaround? Hack up A to depend on B instead, and have your project depend on A.
Surely adding a new dependency isn't supposed to involve mucking with the build files for half of your existing previously fine third party libs just to get the bloody thing building again - such that all dependencies are only referenced once, yet such that every library has it's dependencies indirectly satisfied by whatever it's been configured to depend on.
I assume I was doing something wrong. I probably sunk a good week into consuming docs and trying stuff out to figure out exactly what. I still have no clue. My coworkers couldn't figure it out either.
I wrote wrapper scripts - and later a full blown partial adb wrapper - to fix the silent deploy failures, after one too many hours of wasted debugging sessions (caused by debugging stale builds) made me crack. A few commands to check file sizes and timestamps... a few regular expressions to parse the results... a few debugging sessions when e.g. the installation defaults for "adb logcat" log output format changed between SDK versions...
After reaching a similar snapping point for ANT, I took the slightly less drastic option of switching to gradle for the next Android project I tackled. I remember gradle being merely 50% as terrible as ANT. I seem to have successfully repressed many of my more detailed memories of dealing with both. Huzzah!
Ant is wonderful.
It runs FAST and executes builds properly.
Gradle makes my fans go full throttle, takes minutes to complete builds unless I make use of a background daemon with 2GB allocated to it.
If it wasn't for Android, I would never use Gradle!
Even Maven feels like a pleasure (yes I do enjoy XML).
If not then you shouldn't assume it's Gradle's fault. A lot of Android Gradle builds are slow because they proguard lots of class files, merge large dex files, etc. Which is all optional functionality of the Android plugin, not inherent to gradle.
This is absolutely not insane.
I've saved over a minute per project per build simply by switching linkers (bfd -> gold IIRC?) in a large set of C++ projects. There were several projects - this easily saved 10 minutes per build when touching core libraries.
Considering my experience was that gradle builds were faster than corresponding ant builds (when not much has changed, in codebases with relatively small amounts of Java - e.g. I'm doing small iterations, which I care to optimize for), profiling what exactly is to blame seems worthwhile. I do it for 200ms hitches, why shouldn't I do it for multi-minute builds?
You want a build pipeline so fast that you don't even have a build step? So do I, but devs will still figure out how to add one which may take several minutes (e.g. unit tests.) - better to aim for a practical compromise that lets you iterate fast (hot reloadable scripts and data for example.)
> The fact that people need to do this is the problem.
To move this towards the realm of tautologies - performance problems are problems, yes. So solve them. But profile to ensure you're actually solving the right problem first.
Yes, ideally our build systems already have perfect caching - and could rely on filesystem events instead of directory scans for cache invalidation - and have blazing fast parsing steps, all resulting in subsecond build times.
On the other hand, it's insanely complicated to reach perfect caching for all buildable things - and there's only so much you can do if one of the buildable outputs is a large compressed file, for example (which is a common feature in pretty much every project I see, containing all the assets bundled and compressed in some form for better runtime performance.)
Dumb and simple tends to be more reliable, more understandable, and usually not too much worse. Although sometimes you'll be left profiling the edge cases and adding or fixing the caching involved.
- The build might have dependencies with dynamic versions or changing modules (aka snapshots), meaning that Gradle periodically has to download the latest version.
- The project might have proguard enabled for dev builds, which isn't really necessary. (As long as you smoke test release builds, which is a good idea anyway.)
- The project might have dex merging enabled for dev builds, which isn't necessary unless you need to test something on a pre-ART device.
- Engineers might be passing --clean or --refresh-dependencies, out of habit, when they're not needed.
You could criticize Android's architecture for not being conducive to incremental builds, or you could criticize Android Studio for generating build files with some expensive functionality enabled. But none of this has much to do with Gradle.
Dual core with 8 GB, 500 GB HD, perfectly fine for Eclipse, Visual Studio, MSBuild, Ant, Maven.
No need for performance tricks like Gradle requires.
Do yourself a favor and get an SSD.
- in my experience, it looks like gradle builds can make 100% use of all cores my CPU has. If you are working on Android projects day in and day out, it may be worth getting a CPU with more and faster cores, it will increase your productivity and pay for itself in a short time
- you can build a powerful, but virtually silent PC: big aftermarket CPU cooler, semi-passive GPU, semi-passive PSU, SSDs, no case fans.
If gradle is killing you, I would suggest trying it out.
Warning: we have a few guys in a mobile developer experience team, so I don't know how good it is for indies.
My project involves lots of native code and genrules, though. If you're mostly building Java code I imagine Buck might work well. If starting from scratch I would try Bazel first.
As the OP pointed out - straddling several languages means that syntax and keywords are not always readily apparent when you sit down to code, but knowing where to look for them and refresh your memory quickly becomes an activity all on its own.
This from a guy who is a week away from being 50, and still occasionally puts a ';' at the end of his ruby code blocks.
I've been working with Android for a couple years, and (while I like it) it has it's warts. The architectural patterns required to keep a medium-sized codebase understandable are simply not agreed upon. There are lots of ways to do things, and (as the article points out) even the basic activity + fragment API's are very complex.
I just started playing with React Native, after having some React experience, and it's a breath of fresh air. It feels like cross-platform without obvious negatives, and the rare bonus of being able to wrap + use native components or libraries whenever you need to. You can even share most of your code (even view code for basic views) across IOS and Android. React has a super simple API. The tooling is younger, but is out of the box faster to develop with than Android.
That said, I haven't built a large app in React or React Native, and maybe it bites developers at some scale. No idea how it deals with long-running services, multiple threads, bluetooth or other hardware APIs. But for now, I'm very optimistic.
It's better because React Native is actually rendering native components. Stuff like PhoneGap never feels or works quite right as a side effect of being rendered in a web view.
I'm currently working on a way to make our mobile-tailored website into an app, just because customers keep requesting a _real_ app instead of a webpage.
So there's no worries about being online or offline, just from using React Native.
At this years Google I/O, there were talks how to do that (in the Chrome track).
Unlike the OP, I like and use Android AsyncTasks. I have no problems with Android fragments either.
However, I did have a lot of other concerns with Android - primarily the low quality of Google's SDK for Android. Here is what I wrote about it
This has always been my biggest frustration with Android. I've written a few applications for the platform, and while their architecture leaves a lot to be desired I've never had any real problems with it. However, the immense disappoint and anger that comes from their SDK idiosyncrasies is astounding. Google really just hates stability and nice API's, in my opinion. Everything from GAE to Android, it's always just so terribly frustrating to keep track of any one-off decisions they make without any form of actual communication from the development team.
I've been writing Android code since the G1 days.
What do you mean? Where craigslist entrepreneurs and seed stage startups want iOS apps?
As an example, another commenter noted the Android platform engineers not being opinionated about application development as a "lofty ideal", but more likely this is a consequence of the framework team having enough on their plate. The vanilla Java AOSP API surface (not even considering the NDK, support libraries, Google Services, etc.) is enormous. The Activity lifecycle is complicated, and it's very easy to leak memory or write spaghetti code. There are many ways to do similar tasks, and these also change with time. Etc.
That said, I love being an Android developer, and it is improving at an accelerated rate. To start, Android Studio and Gradle are far superior to the pain of getting Eclipse, Ant and the SDK tools working together.
Yes, Swift is awesome and shiny, but there is so much more to a platform than the language. Java has excellent tooling - great support for debugging, monitoring, automated testing for CI/CD (automated UI testing still needs work, but also improving), static analysis, etc.
The support libraries are also a godsend, enabling you to make an app that looks modern while being frequently updated and handling a lot of the compatibility headache from the platform's diversity.
Finally, there's a lot of great content online. The conferences are great and its expected to see their content on YouTube. Google's Android Developer YouTube channel is also fantastic (shout out to Jo and Ian!), and Google is slowly but surely improving the developer docs and integrating their sample code into Android Studio.
So yes, you do need to understand the new functional reactive approach. You need to know how to write a Gradle build. You have to understand the complexities of proguard rules. It's all pretty frustrating. But I also feel that many of the skills are more easily transferrable - I can also write a Gradle build for a library or I can use IntelliJ to better debug a servlet. With Swift and iOS, there's only vendor you can build for.
I couldn't agree more. Android experience is hard-won. You have to 'discover' and develop an intuition for application architecture and how to use UI components effectively over time.
The upside is a well-architected Android application --using tools like MVP, dependency-injection, and functional-reactive programming-- will have the positive characteristics of a Service Oriented Architecture: encapsulation, statelessness, composability, loose-coupling. This may seem like overkill for an app, but it minimizes the effect of UI lifecycle issues novice and intermediate developers tend to complain about.
Architect a few Android applications in this way and you gain valuable experience composing abstract services together. A competency that is transferrable to backend services and other platforms.
As a frequently frustrated intermediate developer I'd greatly appreciate it. I've just begun using RxJava and Robospice to tame my server endpoint call logic, but I know it's just the tip of the iceberg.
Soundcloud has a reasonable and practical approach on Android: https://www.youtube.com/watch?v=R16OHcZJTno
A good bet is to search Github for projects where common Android APIs or libraries are Rx-ified. You'd be surprised at the economy and simplicity of code you can find in some of the best Rx implementations.
If I had to go back though I'd probably try to find a way to do things once on the web, is React Native this?
Making a typical UI application means reusing lots of widgets provided by the OS, like buttons and sliders, to keep things consistent and make development much faster. If you tried to build a normal UI app inside a graphics engine, you could do it, but you would have to build all widgets from scratch and it wouldn't look like a native UI app.
Instant run is supposed to solve this, but it's too buggy to be useable right now. Sometimes your changes just don't apply, but you never know if that happened or you messed up your fix.
I actually preferred ant since I better understood what it was doing. Gradle error messages are often very vague and confusing, and build times are strangely inconsistent.
Apple, formerly famous for being design hippies who couldnt care less about performance, have topped the mobile performance charts for nearly a decade straight now and with no end in sight. An entire decade! They merely had the wisdom of not choosing java to base their platform on.
I think the problem is Android keeps changing the current best practices. I'm not even sure how to know what those are - if you enter code from the Android tutorial into Android Studio, much of it is deprecated.
In January 2011, the way to do tabs in Android was via LocalActivityManager. Then in February 2011, ActionBar.Tab was added. By July 2011, the LocalActivityManager way was deprecated, and ActionBar.Tab was was pointed to as the way.
Then in November 2014 with the release of API 21, ActionBar.Tab was deprecated ( https://developer.android.com/reference/android/app/ActionBa... ). So what do we do for tabs now? Who knows? The most current tutorial ( https://developer.android.com/training/implementing-navigati... ) is still telling you to do it in the way that was deprecated two years ago.
That's what is maddening with Android - they have a way to do tabs, add a new way, deprecate the old way within five months, then three years later change their mind and dump the new way - without changing the documentation and telling you the new way to do it, it's all just deprecated.
The tutorial is full of deprecated code. What's the new way to do it? Who knows?
A few years ago some corporate director at Google must have gotten a directive to push Google TV. So then they were pushing all apps to work with Google TV. I guess that fizzled out. The latest thing is making sure our legacy apps work with Chromebooks which allow multiple apps on the screen at the same time.
I don't mind Google and Android continually chasing the new shiny, but I wish they wouldn't have a tutorial full of deprecated code, I wish they didn't change how they do things such as tabs every three years (three new ways to do it in three years). I wish they fixed bugs instead of implementing new features. On code.google.com, developers post bug reports, then many other developers jump on saying they see the same thing, and...a few years later, it just closed for being obsolete.
Another example of continuous churn - Google Analytics looks like its going by the wayside, to be replaced by Firebase. Admob is now integrated into Firebase. So that's a whole other thing that needs to be redone in an app. You have to run to stay in place.
If you're doing it 40+ hours a week then maybe the ongoing investment is worth it but to me it's a colossal waste of time.
I agree multidex is terrible. Google please fix this.
I do not know when I should use a fragment instead of a view. I know the layout reasons google gives in their developer guide but I don't think I have seen a piece of code that really uses fragments that way. So why?
I do like Android development though.
I guess this is mostly due to all the resource crunching that Android does, and the fact that Android Studio doesn't perform incremental compilation by default.
Another annoyance is that every time a minor change such as incrementing a version number is made, Android Studio grinds to a freeze syncing gradle files.
I think it's Gradle getting somehow into knots and taking a while to resolve everything -- I've got a very beefy computer so it's not about processing power. Gradle is just ridiculous.
For our project, the most time consuming part is... Packaging. Making apk splits is slow, why does it zip the whole thing again if it is just replacing resources?
Maybe fragmented zip files with holes inside are undesired? Because that's what you get when modifying zip files in-place.
Ironically, it was my repurposed Chromebook :)
Google should be spending millions being able to get app development up and running in something like Python. Have your app up and working in 2 minutes without having to learn Java. It boggles the mind that this isn't the case, and that the current tooling environment is soooo impossible to wrap ones mind around.
Transpiling languages like that nearly always ends up messy, and adds another layer of potential bugs to the system. Taking the time to learn the platform will end up better in the long run (at least with the current state of transpilers).
And as it stands, you can write Android apps with a native UI in Java, Kotlin, JS (React Native) and C# (Xamarin). And you if you want you can write business logic using any language that will compile to a C binary (using the NDK).
In order to get any access to the Android APIs, you have to do C-JDK bridging through JNI. And in android VMs, there's a hard limit on the number of symbols you can reference in the lifetime of an app.
It's the equivalent of if python was like "yeah you can use the standard library, but only up to 100 functions!"
iOS, since it goes through the LLVM framework stuff, doesn't have that many barriers to transpiling from other languages. You can just do raw function calls to the OS libs. But Android doesn't allow this, forces you to go through the JNI, and makes you have to work around this symbol limit.
I've found, from experience, that large code bases written in statically typed languages like Java tend to be much more easier to read, understand -- which is extremely critical when working with a team. I use Python for a lot of my personal projects, but for a team project, I would rather use Java than Python.
 Explained in detail here: https://news.ycombinator.com/item?id=12594616
If you want to use Python and native UI components at the same time, you must run Python as a kind-of backend layer, where you call JNI functions from Java which will be redirected to the Python interpreter through C/C++. I have done this with an app that I have on the Play Store  which shares all non-UI code with a web app . Even the charts are similar as they are generated as SVGs on my Python code.
This architecture allows me to have native frontends on different platforms, and I have open-sourced PyBridge  to be used as starting point for everyone who wants to use something like this: basically, you send JSON messages from Java to Python with the name of a function and the arguments, and you get the response.
I particularly liked Cappuccino. It's basically a port of Cocoa to the web. You could design your interface in OSX's Interface Builder. The project is still around and is still being worked on. Sproutcore was pretty similar, and is also still around. Neither of them are being developed as heavily as React or Angular 2, but they have both been mature for a long time, and perhaps don't need a lot of work to be done on them.
Maybe it's just me, but I still find 280Atlas and 280Slides more impressive that many web apps that ship today, and they're nearly 10 years old and ran in browsers far slower and less capable than what we have now.
I actually think more developers would frameworks like these if they didn't feel they had to stay on the latest and greatst JS treadmill to remain employable. And I write that as someone who likes React and Angular. They're both sane ways to develop complex apps, but they don't feel that much better than what was possible 8 years ago.
Only after few weeks I learned that we should never use AsyncTask for IO because internally it uses a threadpool of hold your breath 2 threads !
So how do I make all my REST requests ? Through something like Volley.
This library is even more disgusting as it does not support some simple urls such as http://example.org/?id=1&id=2.
So I turned by focus on Services only to learn later that Services are meant for background tasks but run on UI thread.
The best approach to do your own IO is through IntentServices. Something that should have appeared in the first tutorial.
It's nothing like writing 'normal' Java, and the baggage that is bought along isn't worth the effort.
I like Java. I hate Android development.
This will only get worse when Java 9, specially Java 10 gets released.
The raptureinvenice.com page isn’t working -- raptureinvenice.com redirected you too many times.
Anyone having same problem?
Is it better now? What are some of its limitations?
It's still a good choice if your app mainly involves displaying lists and tables of text and images, and data entry forms. The cross platform Map control works quite well too.
I don't remember exactly what is different now from a year ago, but if you list a few of the limitations you faced, I can tell you if they still exist. A quick look at the Pages, Layouts, and Controls section of the Xamarin Forms page might tell you if they've added things that were missing last time you tried it: https://www.xamarin.com/forms
I ended up choosing Android because I found more demand for Android developers in the market. I certainly understand some of the OP's frustration with Android development.
There's a lot of silver lining to doing android development for other people. Inflated demand, and all the client side - server side fires have already been put out when the company did the iOS project. So I would say, easier or less stressful.
But I've been at this for a while, so there's the possibility I'm just good at it.
Microsoft might have lost the mobile war, but they are on good track to win the hybrid laptops one.
Give it a couple of years and I think it'll be exactly what you're asking for.
Glad to hear it ;-) I'm curious, what have been the main issues for you?