Android Programming Assignments

The programming assignments for this course will involve implementing Android applications. This means that you will have to learn some Android concepts in addition to the distributed systems concepts taught in lecture. This is typical in that much distributed systems development uses some middleware or distributed communication library. There will be minimal lecture time spent on Android.

Development Environment

All projects for this course must be buildable using gradle under Android Studio 3.0.1, and target Android SDK version 19. (SDK versions 23 and above use a fine-grained permission structure that makes automated testing more difficult for our purposes, and newer SDKs are much more resource-heavy in the emulator.) The provided starting code will meet these requirements.

It will be assumed that you are using a recent Linux distribution (I will be testing things on Debian 9 (stretch) and Ubuntu 17.10). You are free to use whatever environment you are most comfortable with, but course staff cannot provide technical support for your system or running the Android tools on your system.

Android Studio Compatibility

If your AVD emulator won’t start or crashes shortly after startup, you may have C++ library compatibility problems. In particular, if you see log messages like the following, you have this problem:

9:30 AM	Emulator: libGL error: unable to load driver: i965_dri.so
9:30 AM	Emulator: libGL error: driver pointer missing
9:30 AM	Emulator: libGL error: unable to load driver: i965_dri.so
9:30 AM	Emulator: libGL error: driver pointer missing
9:30 AM	Emulator: libGL error: failed to load driver: i965
9:30 AM	Emulator: libGL error: unable to load driver: swrast_dri.so
9:30 AM	Emulator: libGL error: failed to load driver: swrast

Fixing this requires removing the C++ library bundled with the AVD emulator in Android Studio, and depends on the C++ library on your system having sufficient compatibility with the prebuilt Android Studio binaries. Assuming that your Android SDK is installed in $SDK, try the following:

cd $SDK/emulator/lib64/libstdc++
mkdir backup
mv libstdc++.so.* backup

This puts the bundled standard C++ libraries in a location where the emulator will not find them, hopefully causing the (working) distribution-supplied libstdc++ to be used.

Paths and Environment

When you install Android Studio, it will install your Android SDK to some directory (if you use the default configuration, this will be something like $PATH/Android/Sdk). This path is the “Android home” directory. You will need to set it and some other environment variables as follows:

ANDROID_HOME=<installed SDK path>
ANDROID_SDK_ROOT=$ANDROID_HOME

You will also want to put the following directories in your path:

$ANDROID_HOME/tools/bin
$ANDROID_HOME/platform-tools
$ANDROID_HOME/emulator

Without these additions, some of the course scripts will not work properly.

Project Assistance

Students may not debug each others’ code! This is a violation of the CSE department Academic Integrity Guidelines. You may request assistance from the instructor or TAs for the course. Before requesting assistance:

  • Try to debug the problem yourself first!
  • Remove as much extraneous debugging code as is practical
  • Check the remaining code into Github
  • Contact the teaching staff (or visit TA office hours) with:
    • The revision on Github of the code displaying the problem
    • A concise description of the problem, including how to trigger it (if applicable)

Project Debugging

First, grading scripts are not unit tests. Write tests for your programs as appropriate.

Learn to use the Android Studio debugger. It will cooperate with an Android emulator instance to debug your application with breakpoints, watchpoints, exception traps, etc. Documentation for the debugger can be found on the Android Studio pages.

As the Pragmatic Programmers say:

“select” Isn’t Broken: It is rare to find a bug in the OS or compiler, or even a third-party product or library. The bug is most likely in the application.

Assume that the bugs you find are in your code, not the grading scripts, IDE, compiler, Android, etc. Look at those things only after you’ve ruled out your application.

Instrument your code with timestamped debug logs. You may need to correlate actions between multiple hosts! If your protocol has logical clocks, unique IDs, or identifiable causal relationships, log those, too. They may help you sort out concurrency problems.

Best Practices

Don’t put it off. The projects for this course can take a long time, particularly if you’re learning Java and/or the Android programming model along with the course material. Start early, figure out what you already have a plan to handle, and come up with a plan to handle the rest. Leave time to explore other options if your first approach isn’t working out.

Develop a model for your concurrency control — don’t just wing it. Know what fields/objects/etc. are protected by what monitors, in what order the monitors should be acquired, and what protocols govern the manipulation of data in your application. Wherever possible, use a single thread with message passing and event handling to eliminate “true” concurrency. Test your model for correctness!

Write beautiful code. Well-formatted, clear, thought-out code is easier to write, easier to debug, and easier to maintain. Develop your code as if you’re producing a product. Sometimes tidying up and documenting messy code can help you find that elusive bug.

Resources

The Java language documentation, Java Platform API Specification, and the Android 5.1 APIs will provide most of the programming resources you need. Of particular interest may be Threads and Locks in the Java language manual.

There are some video tutorials for this class that you may find helpful.

FAQ

Q: The Android emulator dies immediately. What is going on?

A: First, check Android Studio Compatibility above, you may have a problem with libstdc++. Once this problem is eliminated, if you still have trouble, make sure that $ANDROID_HOME/tools is not in your $PATH.

Q: The Android emulator is generally working, but one or more of my images show an error like this:

emulator: ERROR: A snapshot operation for 'avd0' is pending and timeout has expired. Exiting...

A: The emulator crashed or otherwise damaged its snapshot state. Try running emulator -wipe-data @avd0, where avd0 is the name of the emulated image that will not start.