Category Archives: Android

Principle of Least Astonishment

The Principle of Least Astonishment is well put by Wikipedia: “People are part of the system … the principle aims to exploit users’ pre-existing knowledge as a way to minimize the learning curve.” This principle is often demonstrated with UI design, but equally applies to API’s and programming models.

Let’s look at this principle in action for programming models.

Let’s get some Context

In Android, there’s a way to bind a click listener in the UI xml to a method in the code. This is the same functionality provided by HTML elements and Javascript, by the way, so this is a pretty normal paradigm that pre-dates Android. You can see from the Android documentation:

“you can assign a method to your button in the XML layout, using the android:onClick attribute. For example:”

 <Button
     android:layout_height="wrap_content"
     android:layout_width="wrap_content"
     android:text="@string/self_destruct"
     android:onClick="selfDestruct" />

“Now, when a user clicks the button, the Android system calls the activity’s selfDestruct(View) method. In order for this to work, the method must be public and accept a View as its only parameter. For example:”

 public void selfDestruct(View view) {
     // Kabloey
 }

So far, so good, right?

Android Fragmentation (No, Not That Fragmentation)

Recently I was converting some of my Android Activity code to use Fragments. I had a number of elements in the UI bound to methods in my Activity via “onClick”, so needed to copy those over into my new Fragment classes.

Let’s play fill in the blank:
The onClick in the layout bound to an Activity calls a method in that Activity.
The onClick in the layout bound to a Fragment calls a method in that ________.

What should we put in the blank here? If you are a new Android developer (like me), you might say “Fragment”. That’s what I thought, and I was wrong. If you are an experienced Android developer, you might say “… Fragment’s containing Activity” which would in fact be the correct answer.

Surprise, Surprise

I’m not the only person who got that fill-in-the-blank wrong. This scenario comes up from time to time.

Now, the solutions are easy to understand and implement. And I’m sure the Android development team had good reasons for this particular programming model. But I would argue that whatever those reasons were, the tradeoff was a violation of the Principle of Least Astonishment.

We were surprised that the first approach we thought of didn’t work and instead blew up with an Exception.

We were surprised to discover that the structures that apply to programming Activities did not apply to programming Fragments (which share many similarities with Activities).

We were surprised that the correct approach was a different programming model: programmatically assigning click listeners instead of using the onclick attribute.

Conclusion

Keep the Principle of Least Astonishment in mind as you design user interfaces, API’s, or programming models. An unsurprising piece of software saves your users time and frustration, which in turn saves the software company time and frustration (and money). This makes everybody happy!

Advertisements

Leave a comment

Filed under Android, Software Engineering

SQLite Database From Tutorial To Actual Use

The standard Android training site has a useful guide on getting started with the built-in SQLite database. It gives us as new developers the idea of where to start, and allows us to start writing code with it almost immediately.

However, this guide has a critical gap: it does not mention how much more there is more to using the database than those few sample lines. It does not mention where to go next to find out more. We can easily read the guide and come away with the false impression that this way to access the database is the end of the story… until everything breaks and we need to start googling or looking through the sample applications and find out how much more there is to using the database *correctly*.

Here are the missing steps between the guide and functioning code.

Missing Step #1: Manual Transaction Management

To anybody used to using @Transactional annotations, manual transaction management is not the first thing that comes to mind when coming to Android for the first time. Yet, transaction management is critical in this environment. Here is the code that you actually need to use. Think of this as a standard structure that you’ll need for all of your interactions with the database.

// we can begin the transaction outside of the try block
database.beginTransaction();
try {
  // database insert / update  / etc goes here
  database.setTransactionSuccessful();
}
catch(Exception ex) {
  // log or rethrow as you like
  // this dummy code is here to provide a convenient breakpoint
  String cause = ex.getMessage();
  throw ex;
}
finally {
  // always end the transaction in a finally block!
  // don't leave transactions hanging around!
  database.endTransaction();
}

Missing Step #2: Managing The Database Throughout Activity Lifecycle

In the Activity, the database is opened in the onCreate() method. Note that we must have an implementation of SQLiteOpenHelper per the SQLite guide, and that the Context it takes can actually be the Activity since Activity extends Context.

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  SQLiteOpenHelper helper = new MyDatabaseOpenHelper(this);
  database = helper.getWritableDatabase();
}

Correspondingly, in the Activity, the SQLiteDatabase that we obtained from SQLiteOpenHelper.getWritableDatabase() is an open resource that must be closed when the activity is destroyed.

@Override
public void onDestroy() {
  super.onDestroy();
  database.close();
}

Conclusion

That’s it! With these extra steps to supplement the official guide, we can write fully functioning code against the SQLite database.

For more information: the official sample apps do include some sample applications that use a database. Presumably BasicSyncAdapter is the best option at this point (the others being in a “legacy” area).

SDK/samples/android-19/legacy/NotePad
SDK/samples/android-19/legacy/SearchableDictionary
SDK/samples/android-19/legacy/ApiDemos
SDK/samples/android-19/connectivity/BasicSyncAdapter/BasicSyncAdapterSample

Even with functioning code, there is more to learn about how to use it *better*, such as how to open databases in a background thread to improve performance, and a full analysis of using an Android ORM library. For now: enjoy using the database on your Android device!

Leave a comment

Filed under Android, Software Engineering

How to set up unit tests for Android / Gradle

In a recent post we found that maven and gradle are designed for unit testing but not for integration testing (although gradle makes it fairly easy to write separate integration tests).

In Android, it turns out that there is an extensive testing system in place, but that it is not for unit testing, it is for integration testing (actually running your complete application on connected devices). Hilariously, Android seems to have the inverse problem of what we saw in maven and gradle: integration tests are baked in to the system, and unit testing requires special work.

To this end, after having read the android guide on testing with the android gradle plugin, I wanted to set up JUnit tests for my POJO’s that don’t run with the instrumented tests. The idea was that tests for code that doesn’t depend on Android should be very fast (and facilitate TDD).

Unfortunately, after much googling and experimentation, I was forced to the conclusion that simple unit testing is just not supported out of the box with android and gradle. Indeed I was not able to make it work the way I’d like. The best solution I can come up with for the time being is that any code that is completely independent of android is best placed in its own project (say, a sibling to the android application in the gradle main project) and run unit tests there.

If anybody reads this and has ideas, feel free to drop an answer on StackOverflow.

Leave a comment

Filed under Android, Software Engineering