
Android Development Tips For iOS Devs - appbot
http://stuartkhall.com/posts/android-development-tips-for-ios-devs
======
krschultz
I recently went in the opposite direction (Android -> iOS). Forget all of the
flame wars. If you know one, dabbling in the other is a great learning
experience. The two platforms are running roughly the same hardware and facing
roughly the same challenges, and the software architects at Google & Apple
have chosen different ways to solve the problems.

Sometimes the patterns feel similar. You can rig up an iOS tableview/data
source delegate/fetched results controller to look almost exactly like an
Android listview/adapter/loader. But in other areas they function completely
differently. It is well worth the time spent learning the other IDE and
language. My Android app is better because of what I have learned in iOS and
vice versa.

~~~
sreyaNotfilc
I agree. I just started learning Android development about a month ago with
Xamarin C#. Although its in C#, as a .net developer there are so many other
things to learn.

Its exciting really. You see similarities and you also see differences. I
think this helps more than it hurts since these "new ideas" will help me with
the other environment (and vice versa).

This actually got me interested in learning other languages/frameworks (php,
haskell, ruby on rails). After I get the hang of Android, I want to play
around with an iOS app from scratch. Sure, I could use some conversion
software to do this job. But, I'd rather not. I like to understand what's
going on under the hood. I guess its the CompSci in me.

I guess what I'm saying is that I think it is so much better to have a
universal understanding of these technologies then to blindly stick to one
"team".

As an aside...didn't Facebook mentioned they used PHP not because it was
"better" but because it happened to be the technology that worked for what
they were doing at that time?

------
mncolinlee
An important correction: Unlike iOS, Android does not come with a simulator.
It has an emulator. That explains many of the differences in startup speed and
performance. A simulator runs natively and does not have to emulate the ARM
machine code on your x86 device. The Android emulator is theoretically more
accurate and runs the entire Android OS, but the cost penalty is huge.
Therefore, most Android developers test small changes initially on a device.

[http://programmers.stackexchange.com/questions/134746/whats-...](http://programmers.stackexchange.com/questions/134746/whats-
the-difference-between-simulation-and-emulation)

~~~
chimeracoder
> Therefore, most Android developers test small changes initially on a device.

That's also because deploying an APK on a test device (or several devices) is
_way_ easier than deploying an IPA on an iOS device.

As someone relatively new to iOS this past month or so, I was shocked by the
number of hoops I have to jump through just to take a piece of code I've
written and put it on a device that I own and is sitting right next to me[0].

Coming from Android development, I never thought twice about this - it's easy
to push the APK to my phone as part of the build process, and I don't even
have to plug my device in to do so.

[0] Including shelling out $99 for a certificate that gives me the permission
to do so.

~~~
mncolinlee
I would argue that debugging is also infinitely easier in the Android world,
since plugging a phone into USB and authorizing ADB gives you full control to
see everything on the phone. You can get full logs and debug control over the
hardware. You can push and pull stack traces and files to and from the device
with a single, three operand command line and obtaining hardware screenshots
requires only a click in IDE.

Android also has a plethora of debug options hidden in a special device
settings menu that can be hugely helpful for troubleshooting performance
issues.

~~~
stefan_kendall3
Uh. It's way harder to setup an android device for debugging. I just had to
plug in my iphone and tap "use for development" at the prompt.

I'm porting an iOS app to android right now, and android is way behind on the
development side of things.

~~~
krschultz
After you setup the provisioning profiles correctly, get the build schemes
right, etc etc. Oh and don't forget to send Apple your tax id!

I would highly recommend using Android Studio + Gradle over Eclipse. IntelliJ
is a significantly better tool for writing and refactoring code than XCode.
Some of the tight integrations between XCode and the phone are superior
(especially around profiling), but overall I think IntelliJ is a much stronger
tool. Even something as simple as doing layout is vastly better on Android.
There is no choice between 'in code or in Interface Builder'. XML + the viewer
in Android Studio is the best of both worlds.

I also think Relative Layouts accomplish 99% of what auto layout accomplishes
in a much friendlier manner.

~~~
stefan_kendall3
I didn't have to do any of that. Xcode creates provisioning profiles for you,
and appcode created the schemes I needed. I think Xcode does a decent job as
well.

And you only need a tax ID if you're trying to imminently release a paid
application or an app with IAP. But we're discussing development, not release.

------
V-2
"A trick often used by iOS devs is to use the tag of a view to hold lookup
information, such as offset in arrays. With Android you can shove the entire
object into the tag; pretty useful."

Yes, but if it's something like a ListView, don't put offset in array there,
because the views are recycled (when user scrols), so you're likely to end up
with corrupted data. I got bitten by this in the beginning. You can go to
great lengths to prevent this from happening, but it will be hard for a
reason, because that's abusing the design principles.

I'd recommend reading up on the ViewHolder pattern in this context.

Long story short: cache all the references to all specific sub-views of the
row view in the tag (so you don't have to retrieve them again and again) -
that's good practice. Just don't store any position-specific data in it.

Watch
[http://youtu.be/wDBM6wVEO70?t=9m50s](http://youtu.be/wDBM6wVEO70?t=9m50s) \-
very informative

~~~
reidmain
You can also just create a category on UIView that defines a property which
could store a object.

@property (nonatomic, strong) id context;

or

@property (nonatomic, weak) id context;

if you are sure the context will always exist.

------
V-2
"I used to think the iOS simulator was painful, now I realise it's pretty
awesome. Skip the Android simulator all together and deploy to a real device,
or be prepared to spend a lot of time waiting."

With its "native" emulator, yes, but there are better alternatives like
Genymotion. Giving up on them is not good development advice.

~~~
stefan_kendall3
The android emulators not only are bitterly slow to launch and use, but they
do not reflect actual device performance, unlike the iOS simulator.

This makes automated testing impossible on the simulator, whereas in iOS I can
run my full test suite (400-something tests) in the simulator in a couple
seconds.

~~~
LordIllidan
I find the simulator a bit deceptively fast, compared to a low spec iPhone
(e.g. iPhone 4).

Also, there's the case sensitivity - iPhone Simulator is not case sensitive
(maybe depends on your filesystem settings), while the device is case
sensitive. This can be really annoying the first time round.

------
dotnick
You can get a pretty responsive emulator if you use an x86 ABI and HAXM[0].

[0] [http://software.intel.com/en-us/android/articles/intel-
hardw...](http://software.intel.com/en-us/android/articles/intel-hardware-
accelerated-execution-manager)

~~~
higherpurpose
You will get a faster emulator, but since x86 is used on like sub 1 percent
Android devices, won't that be more like using a simulator, which would make
it just as useless/useful as a simulator? Does the x86 image contain support
for ARM, too?

~~~
ZoFreX
For most cases the underlying architecture doesn't really matter. "As useful
as a simulator" is also quite a high standard for Android, seeing as there is
no simulator available.

------
Nemisis7654
Some things I would note:

* Do not use getBaseContext() like he does when he created the new Activity. Use getApplicationContext for most things (unless an Activity is required) as this is guaranteed to be the same throughout the lifetime of your application.

* For log alternatives, checkout Timber by Jake Wharton ([https://github.com/JakeWharton/timber](https://github.com/JakeWharton/timber))

* I would suggest using the Build.VERSION_CODES when making the check against which version of android the device is ([http://developer.android.com/reference/android/os/Build.VERS...](http://developer.android.com/reference/android/os/Build.VERSION_CODES.html))

~~~
minikomi
And if you want colored logcat in a terminal window:

    
    
        alias lc="adb logcat | sed -e $'s/^I.*/\e[0;94m&\e[0m/g; s/^D.*/\e[0;92m&\e[0m/g; s/^W.*/\e[0;93m&\e[0m/g; s/^E.*/\e[0;91m&\e[0m/g'"

~~~
myko
Jake Wharton also has a neat fork of Jeff Sharkey's colored logout Python
script which is pretty awesome:

[https://github.com/JakeWharton/pidcat](https://github.com/JakeWharton/pidcat)

------
kenrikm
"Tag A trick often used by iOS devs is to use the tag of a view to hold lookup
information, such as offset in arrays. With Android you can shove the entire
object into the tag; pretty useful."

No.. Just no. That's considered really bad form. The tag of a view should not
be used (Abused) to hold an index etc.. that is linked to the data set.

------
jongold
This is excellent, thanks! Has anyone got similar resources for iOS devs
looking to try out Android?

------
stefan_kendall3
If you're commenting on the ease or difficulty of building iOS/Android native
apps in this thread, and you aren't actively building an app for both or have
built one before, you probably don't know what you're talking about.

The eco-system for building and deploying apps on both sides has gotten way
better in the past couple years. There are pros and cons to both sides of
development.

~~~
stefan_kendall3
iOS pros: Blazing fast simulator, ability to run tests through xctool or
Xcode. Autolayout is extremely powerful, and you don't need to write state
suspend/restore code for landscape rotation.

If you're writing a new app, you can probably exclusively target iOS7.

iOS cons: The device limit. This makes deploying apps to your users more
difficult than it should be. Xcode is also an extremely weak IDE, but AppCode
makes up for it.

Android pros: Faster iteration with releases, because no review process.
You're also less likely to fight app review for dumb shit.

The nexus 5 is only ~$420 with shipping.

Intelli-J support.

Android cons: Emulator is for all purposes unusable. You will need to buy a
device. Fragmentation of the OS across all devices.

~~~
pjmlp
> Android cons: Emulator is for all purposes unusable.

At least on Windows it is quite usable for OpenGL ES emulation, when using
Intel's virtualization driver.

------
rizwan
UIViewControllers fall somewhere between an Activity and a Fragment.

In particular if you use any kind of view controller containment (custom
container view controllers), you can only do that with fragments, and only
then with Android 4.0+.

As someone who's looked at building tablet apps, the containment is a good
thing to consider. In these cases, iOS makes it easier to combine your
existing view controller hierarchies, while there are some idiosyncrasies
(only 1 action bar across the top of a "split view controller") on Android
still that don't always make things easy (in my opinion).

------
warrenmiller
"When the user rotates the device your activity is completely reset" You just
need to set " android:configChanges="orientation|keyboardHidden" in the
manifest.

This is very well documented.

~~~
ZoFreX
This is definitively the wrong way to handle the problem he describes in the
article. Even if you set this in the manifest you need to store your state and
resume from it correctly. An orientation change is the most common
configuration change that causes activities to be restarted, but is far from
the only one.

~~~
srcreigh
This. The most common other case in which you need to restore state is when
your app goes into the background, and is restored.

------
nsmnsf
My experience with ListView was... weird. It doesn't ask you for a height for
each row like UITableView does, just for a row count. Then, it measures your
views as you return them. This meant that the scrollbar was completely
unreliable, it would resize based on the height of the currently visible
views. Is there an obvious way around this that I'm missing? ListAdapter
doesn't have anything for specifying height.

~~~
srcreigh
This is by design in Android. It's very computationally heavy to ask for the
heights of each ListView item. Unfortunately I wasn't able to dig up my
reference to this. :(

Two more things:

1\. The wormy scrollbar is actually standard on Android: the messaging app
does it, IIRC even the twitter app on Android does it. So even though your iOS
experience tells you it's weird, any users of yours on Android likely won't
notice.

2\. If your items are all the same height then your scrollbar won't be wormy.
So if this is really that important to you, then make your ListView return
items that all have the same height.

~~~
xsmasher
> It's very computationally heavy to ask for the heights of each ListView
> item.

Can you expand on that? Do you mean that it's expensive for the OS for some
reason, or do you mean that it's expensive for your (client) code to compute
the height of each item?

It seems like in most cases it's a simple method like "return isHeader :
HEADER_HEIGHT : ITEM_HEIGHT;"

~~~
BitMastro
For the OS. Imagine 999 rows containing one line of text and the last one
containing a long text spanning maybe 30 lines.

To calculate the scroll accurately you need to calculate the height of 1000
elements to get the full height.

Instead in the common scenario you just calculate the height of the rows
displayed on the screen and estimate the height using the average and the
count.

~~~
nsmnsf
I don't have to imagine this, though, I've done it on iOS. It works fine,
because you're rarely working with 1000 items at once. With pagination, you
cache the old results, and only calculate the new 50 or so rows at a time.

~~~
BitMastro
On the other end, pagination is rarely used on Android, and calculating the
height of a single row can be more expensive since it has to layout the
children hierarchy for a row according to the screen dimensions.

~~~
nsmnsf
This type of layout is generally limited to social feeds, where pagination is
pretty much mandatory (you have to request more results from an API). Anything
entirely client-side typically uses fixed height rows.

~~~
BitMastro
I see your point, but this layout is used also for variable height images,
variable lenght text, compound layouts, etc. The equivalent of pagination on
Android is usually done using pull to refresh (horizontal swipe gestures are
usually used to change topics more or less).

For something completely client side it is possible either to specify a fixed
height or change the smoothScrollbar attribute of the listview (it is more
expensive though and not used very much).

Nobody complains, I guess everyone is just used to the way it is. :D

------
yogo
If you want a sort of CoffeeScript experience instead of Java you can also go
with Xtend [0]. It's supported best in Eclipse but I do find the cleaner
syntax a bit more pleasing to work with. It's only transpiling to Java so you
can even mix it with Java while updating an existing codebase or for whatever
reason.

[0] [https://www.eclipse.org/xtend/](https://www.eclipse.org/xtend/)

------
Rygu
> Nemisis7654 said:
> ([https://news.ycombinator.com/item?id=7391380](https://news.ycombinator.com/item?id=7391380))

> There is also the excellent Genymotion emulator.

> [http://www.genymotion.com/](http://www.genymotion.com/)

Genymotion deserves to be mentioned in a top level comment. It's the by far
the fastest Android emulator and it works brilliantly simple.

------
higherpurpose
Android uses an _emulator_ not a simulator.

~~~
diminish
And It took me 10 mins to download the proper files andrun it using Intel
virtualization, and my app runs faster than on my smartphone..

------
runamok
If you install the Android Intel Atom (x86) drivers and use that emulator,
performance is much improved.

------
TheHippo
If you looking for an simulator instead of an emulator I would can recommend
genymotion. ([http://www.genymotion.com/](http://www.genymotion.com/)). It's
VirtualBox based and incredibly fast.

