Installing the Android SDK on a headless server doesn’t seem to be very well documented. I recently needed to do this to get the SDK installed on a TeamCity build agent to automate Android builds and tests.
Below are some simple instructions to help you along the way. I’m using a Mac, so you may need to use slightly different commands if you’re using Linux.
When trying to build the Android Hello World tutorial in Eclipse I ran into an issue where the application would just crash when I tried to run it:
[2010-05-04 01:53:46 - HelloAndroid] ------------------------------
[2010-05-04 01:53:46 - HelloAndroid] Android Launch!
[2010-05-04 01:53:46 - HelloAndroid] adb is running normally.
[2010-05-04 01:53:46 - HelloAndroid] Performing com.example.helloandroid.HelloAndroid activity launch
[2010-05-04 01:53:46 - HelloAndroid] Automatic Target Mode: launching new emulator with compatible AVD 'myAVD'
[2010-05-04 01:53:46 - HelloAndroid] Launching a new emulator with Virtual Device 'myAVD'
[2010-05-04 01:53:58 - HelloAndroid] New emulator found: emulator-5554
[2010-05-04 01:53:58 - HelloAndroid] Waiting for HOME ('android.process.acore') to be launched...
[2010-05-04 01:53:59 - Emulator] 2010-05-04 01:53:59.501 emulator[10398:903] Warning once: This application, or a library it uses, is using NSQuickDrawView, which has been deprecated. Apps should cease use of QuickDraw and move to Quartz.
[2010-05-04 01:54:23 - HelloAndroid] emulator-5554 disconnected! Cancelling 'com.example.helloandroid.HelloAndroid activity launch'!
The crash report was identifying the problem as a segfault:
Process: emulator [10472]
Path: /Applications/android-sdk-mac_86/tools/emulator
Identifier: emulator
Version: ??? (???)
Code Type: X86 (Native)
Parent Process: eclipse [10468]
Date/Time: 2010-05-04 02:25:41.153 -0500
OS Version: Mac OS X 10.6.3 (10D573)
Report Version: 6
Interval Since Last Report: 2558914 sec
Crashes Since Last Report: 4
Per-App Crashes Since Last Report: 2
Anonymous UUID: C5F178C1-5290-4CA9-AD6E-E9C4F5582754
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000000001fd2f000
Crashed Thread: 3
The explanation
As best I could tell a snapshot of my AVD was saved while the previous version of HelloAndroid was running. And so when I went to run the new version of HelloAndroid (after making some code changes) the new package was copied over and then the emulator was restored. At this point it was in a corrupt state where the old version was still in memory but the new version existed in local storage. This may or may not be exactly what was happening, but it appeared to be what was causing the app to crash.
The fix
For me, I simply turned snapshots off on my AVD. To do that in Eclipse you can just follow this menu/button options:
Window -> AVD Manager -> [select your avd] -> Click Edit -> Uncheck “Enabled” next to Snapshots
If this doesn’t work you can also delete the AVD and create a new one with the same settings but with snapshots disabled.
If you’re still running into trouble, check out this thread over at StackOverflow. It didn’t solve my problems, but your mileage may vary.
If you’re trying to communicate with a web service or scrape any data from the web in your Android application, you might run into an exception like this:
E/AndroidRuntime(673): java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.helloandroid/com.example.helloandroid.HelloAndroidActivity}: android.os.NetworkOnMainThreadException
From Google’s documentation:
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it’s heavily discouraged.
The fix
The problem here is simply that you need to make your web service calls (or what-have-you) on a separate thread. So, quite simply, you’ll need to look into how to do threading with Android. Unfortunately this can be a bit of a pain because you need to make your service calls on a separate thread, but you need to update the UI on the main thread. Normally this would require passing data between the threads, which involves handlers or other complexities. Luckily the Android platform provides the Async Task to handle this, which alleviates some of this complexity and may help you avoid some clutter in your code.
Useful documentation to migrate your network calls to threads (or Android’s Async Task)