
What we wish we'd known before building the Prismatic Android app - nstevens
https://github.com/nstevens/androidguide/wiki
======
Ologn
I primarily program Android and have talked to many other Android programmers.

The primary blunder companies make on doing an Android app is they pretend
they're making an iOS app. This is very widespread.

The company has a database. They have a website. They have an iOS app which
connects to a web API connected to that database. They have a designer who
makes his 2 (or 3?) designs for each iOS form factor.

Then they decide to make an Android app. The web API is usually OK. But it
becomes decided that the company will ignore that Android's come in tablets,
very small phones with low resolution, phones with very high resolution,
"phablets" etc. It becomes decided that the goal will be to make a pixel
perfect design (just like for the iPhone!) for the Android phone the designer
has, and perhaps the other one the boss has, and then to just pretend that the
other 99% of the Android market does not exist.

There is more Android work then experienced Android programmers, so some
inexperienced kid right out of college is the programmer on the project, who
is easily intimidated by the designer. They proceed this way until weeks and
months go by and the CEO realizes the app looks like junk on tablets and most
phones, and then blames the programmer for this situation.

Anyone thinking of stepping into a role as an Android programmer should get
everyone on the same page about the UI goals before he agrees to work on the
project. Especially between you and the designer and whoever your common
management is, perhaps all the way to the top. Because the easy way is for the
designer to do what he did for iPhone - 2 designs for the 2 phones he has
access to, which are pixel perfect (which is completely pointless if it looks
like crap on 99% of phones).

This situation arises again and again and again.

If there's any secondary thing, I guess it would be how far back you want to
support Android in terms of versions. You really don't want to support
something before v3.0 if you can avoid it.

~~~
nstevens
Completely agree. Some of the unhappiest engineers & designers I know are on
teams trying to copy the company's iOS app on Android.

We were admittedly in the position you describe: a company of majoritively
iPhone users who shipped the web & iOS apps, cleaned up the API and were
starting on Android.

I don't think there's a perfect solution but we found digging into some of the
guides & sample apps listed here to be particularly useful:
[https://github.com/nstevens/androidguide/wiki/General-
Androi...](https://github.com/nstevens/androidguide/wiki/General-Android-
templates-&-education#general-education-and-other-guides)

We also ordered a range of devices and hooked them up to our Play Store alpha
channel so every build had to go through the 3" phone and 10" tablet test.

Finally, it helped to have a couple hard core Android users on the team who
could explain why simple features like the 'back' button are truly game
changers. There's a good post on some of these differences here:
[http://paulstamatiou.com/android-is-
better/](http://paulstamatiou.com/android-is-better/)

------
turnip1979
As someone who is rapidly becoming an old-timer, I have to say I miss the old
days of Make. It was everywhere and had weird quirks. But you didn't need to
spend too much thought on it. These days, I see projects using Gradle, Maven,
Ant, Ivy, ... and it makes me feel like yet another tool I have to to learn in
order to use X. As a technophile, I'm not against the new new thing. Newness
in language is fantastic .. lets us express ideas or concepts that were
previously hard to do. The explosion in tools that do somewhat similar things
makes me feel like we're doing the wrong thing as a community. I have an equal
disdain for devops solutions like Chef, Puppet, CFEngine, Ansible, whatever.
Is software not mature enough to just standardize on a few and get on with it?
Surely there is not much in it for the winners (maybe I am deluded about
this). Anyways, rant over.

P.S. I was being facetious about missing Make. Point stands.

~~~
twic
It might be accurate to say that we're doing the wrong things but iterating
fast. That's why we have this tumult of tools. Software is definitely not
mature enough to just standardise on a few of them.

I feel confident in saying that because the thought of permanently
standardising on any existing build or configuration management tool fills me
with horror. In the JVM world, ant is inadequate, Maven is diabolical, Gradle
is a huge step forward but has many warts and one or two fundamental mistakes,
and sbt is just vile. Gradle is good enough to be getting on with, but i'm
looking forward to the next step.

Provided, that is, that the next step is taken after learning from previous
steps. Sometimes that happens - Ansible and Salt are clearly attemps to
improve on the overcomplexity of Puppet and Chef. Sometimes it doesn't - i'm
not sure that Gulp or Leiningen do anything to help.

~~~
dcposch
> Gradle is good enough to be getting on with, but i'm looking forward to the
> next step.

Check out Buck. It's fast, the codebase and general complexity is a tiny
fraction compared to Maven or Gradle, and it's more sound in at least one
fundamental way. (It uses file hashes instead of modtimes to figure out if a
task has to be rerun.)

I agree with the rest of your post. Most build systems suck. Here's an off-
hand idea:

All build systems I know work share the same core concept, a directed acyclic
graph of tasks. Each task has inputs (which might be the output of another
task) and if the inputs are changed then the task is rerun. That same idea
also covers a lot of systems for data processing.

Why can't we have a simple, minimal tool for doing _only that_? Then, we could
plug in different task definitions for different uses (eg building a Go
project, a Java project, or running a data pipeline).

This seems preferable to a bunch of different application-specific build
systems that each roll their own DAG, and their own DSL for defining tasks.

~~~
rwallace
We do have such a tool. It's called make.

~~~
sorbits
And the “modern” reimplementation of make is ninja:
[http://martine.github.io/ninja/](http://martine.github.io/ninja/)

------
BitMastro
Another useful resource [https://github.com/futurice/android-best-
practices](https://github.com/futurice/android-best-practices)

~~~
on_and_off
best practices sounds a bit pretentious to me, 'how we dev at Futurice' would
be less presumptuous. Some of these points are common senses, other are
arbitrary library or architecture choices that are not going to fit every
project and some just need to be updated ASAP.

------
christop
Regarding the use of Google Play alpha/beta testing, I created a Jenkins
plugin to automate app uploads: [https://wiki.jenkins-
ci.org/display/JENKINS/Google+Play+Andr...](https://wiki.jenkins-
ci.org/display/JENKINS/Google+Play+Android+Publisher+Plugin)

Though personally I use HockeyApp as you can upload iOS/Android apps and they
become immediately available to testers — no waiting for several hours for
your apps to appear, as occurs with Google Play. HockeyApp doesn't tie you to
a particular form of user management either. Hopefully Microsoft doesn't
change too much there.

~~~
nstevens
great! added a link to the wiki

------
jfernandez
Every time I see a post like this I always learn a few new snippets for best
practices. There almost seems like a need for a primer site for all sorts of
languages and ecosystems.

I'm sure something like this exists right?

------
bicx
As an Android developer building and maintaining a larger app, I'm curious:
Are there any performance hits or worrying complexity issues caused by
including multiple paradigm-shifting libraries like RxAndroid, Dagger, and
Butterknife? I've always tried to keep my app slim by keeping out unnecessary
libraries (particularly ones that require I follow non-standard platform
development), but I'm open to change if it's worth it.

~~~
nstevens
I'd say the two most important libraries for our app have been Retrofit &
Picasso. Both are built on RxAndroid so using it as well is a natural
extension. I think most people would probably only need RxAndroid or otto but
we've enjoyed using both. We mainly use the former for chaining network calls
and the latter to maintain a bus of state updates.

Dagger 1.x (which we currently use) certainly helped slim down code size but
it's mix of compile time and run time injection made using tools like Proguard
a bit messy. We haven't made the jump yet but it seems like Dagger 2.x solves
for this: [https://github.com/google/dagger](https://github.com/google/dagger)

Butterknife is just plain useful to avoid a ton of view boilerplate code.

Our app is admittedly not too complicated but so far we haven't seen any
performance issues.

------
vitno
When I think Prismatic, I think clojure(script). Did they write their app in
Clojure?

~~~
loganlinn
Engineer from Prismatic here. The Android app was written with Java. While we
would have loved to build it with Clojure, but support/perf on Android isn't
quite there yet (at least for us).

~~~
nstevens
Libraries like RxJava definitely made it easier
[https://github.com/ReactiveX/RxAndroid](https://github.com/ReactiveX/RxAndroid)
[https://github.com/nstevens/androidguide/wiki/Libraries](https://github.com/nstevens/androidguide/wiki/Libraries)

------
DiabloD3
Lack of Google login while supporting Android is kind of glaring, in the app
itself. Not everyone has Facebook or Twitter.

------
jsnk
Anyone know of a similar doc for iOS?

~~~
surfmike
This document has some good advice: [https://github.com/futurice/ios-good-
practices](https://github.com/futurice/ios-good-practices)

------
fredgrott
I would ask how they dealt with nested fragments pain

~~~
krschultz
Don't nest fragments. Just don't. Fragments are half baked. Nested fragments
are half (quarter?) baked.

In most cased the inner fragment could be made into a custom View, and those
work a lot better. Most new Android developer do not make enough custom views.
They are the fundamental unit of UI re-use. It's relatively simple to extends
FrameLayout or RelativeLayout, encapsulate a view normal views, layer your
logic on top, and you have a nice usable component.

~~~
bicx
As an experienced Android dev, I cannot agree more. I have never had a
particularly fun experience with fragments, although they definitely have
their place. Custom views though... I love them more every day.

