Looking for Work

I’ve really enjoyed the past year or so of “sabbatical”, learning new skills, doing some hobby projects, and spending more time with my kids, but it’s time to look for a proper job again. I suspect I’ll do some freelancing for a while until I find something suitable.

I’m hoping to find something still in the Linux and open source world, maybe moving into Android, and maybe with some management. I enjoyed running Openismus so I hope I can continue doing something similar: managing multiple small teams of highly skilled software developers who work with open source code and collaborative open source methods, while still doing some software development myself. I’d like to continue working with people with such high standards.

I don’t expect this to be easy because:

  • I want to stay in Munich.
  • I’d really like part time or flexible (start early, leave early) hours so I can spend some of the afternoon with my kids.
  • Running Openismus gave me project management experience, but I’m not sure it’s given me enough to call myself a manager rather than a programmer, and I don’t want to stop being a programmer.
  • GTK+ (and gtkmm) experience is apparently no longer such a popular niche. Qt still is but I’m less enthusiastic about it.
  • C++ is still broadly popular, but I’d like to stay away from MS Windows development.
  • I’ve really enjoyed doing Java Android development recently, but I hesitate to call myself an expert Java developer, compared to my C++ skills. Then again, if most Java developers are as bad as most C++ developers, then I must be better than most.
  • Although I’m learning some Algorithm analysis theory at the moment for fun, it doesn’t greatly interest me and I’ve never needed it over the last 20 years. But it seems to have become a popular interview filter.
  • I’m still not a Kernel developer and I still don’t really want to be. I like creating libraries, tools, and user experiences.

Here’s my CV if you think I can be useful.

Processing for Kids

Liam (7) has been playing a little recently with Processing, mostly drawing shapes and moving them around. The Hello Processing interactive video tutorial is an excellent introduction, for kids too. Thanks to Jon Nordby for suggesting Processing.

Liam is gradually working through the Getting Started with Processing book, typing in example code and changing it as the book suggests. Previously he has used Scratch and he’s started using the Lego Mindstorms programming environment, which is surprisingly visually complicated. But Processing is a nice introduction to real text-based programming, where you must type everything perfectly correctly or the computer will complain with incomprehensible error messages.

So far this seems to be the closest modern-day equivalent to my childhood experiences of sitting down with a Sinclair ZX81, Spectrum, or BBC Micro and trying things out from a book on BASIC. The expectations are low so you can easily feel that you’ve achieved something significant.

IMG_20141219_124554

The Processing IDE is a very simple and obvious UI and a Processing hello-world can be just one line, without any platform initialization, without specifying anything about exactly where your output should appear:

line(15, 25, 70, 90);

By default there’s just one screen that you draw on, and all functions and types appear to be in a global namespace. So you can start making things happen without the distraction of boilerplate code and without figuring out where in that mess to put your own code. You don’t need to learn about objects, inheritance, or encapsulation, though of course you should later.

Writing an iPhone or Android app might seem more interesting to modern kids, but they’d have to wade through so much kibble just to get started, while always noticing how far they are from achieving anything like the existing apps they see.

Processing is actually Java. When you write code, that code then seems to be the contents of a method in a (derived?) PApplet class, though you don’t see that other than in some compiler error messages. The functions such as size(), stroke(), point(), ellipse(), color(), strokeWeight(), etc, are actually member methods of this class. You don’t need to import any Java classes to use this API.

Java is fairly forgiving, particularly for the simple examples that people will start with. And it  offers a nice route into object orientated programming without the lower-level pain of C or C++.

Instead of just writing a bunch of code to run and then stop, you can instead define (override) setup() and draw() functions that do what you’d expect. The draw() method can make use of member variables such as mouseX and mouseY (these are not parameters of draw()). Likewise, you can implement keyPressed() and make use of keyCode. So you get a simple introduction to making a program interactive by doing event-driven programming.

Processing is not perfect, and I think you’d feel the lack of a real API and IDE as soon as your project became more serious, but it’s a great introduction to real programming.

PrefixSuffix revived

In 2002 I released a little GNOME app to rename files by changing the start or end of the filename, using gtkmm and gnome-vfs(mm). It worked well enough and was even packaged for distros for a while before the dependencies became too awkward.

I’ve never heard of a single person using it, but I still need the app now and then so I just updated it and put it in github, changing it from gtkmm 2.4 to gtkmm 3, removing the bakery dependency, and changing from gnome-vfs to GIO. I also removed most signs of my 2002 code style.

It seems to work, but it really needs a set of test cases.

I’m sure that the performance could be vastly improved but I’m not greatly interested in that so far. Patches are welcome. In particular, I haven’t found an equivalent for the gnome_vfs_xfer_uri_list() function for renaming several files at once and I guess that repeated sequential calls to g_file_set_display_name_async() are probably not ideal.

screenshot_prefixsuffix

glibmm 2.44.0 and gtkmm 3.16.0

I’ve just done the stable glibmm 2.44.0 and gtkmm 3.16.0 releases with the usual bunch of API additions and deprecations to keep track of the glib and gtkmm API. Thanks to Kjell Ahlstedt in particular for his many well thought-out contributions.

I’ve been maintaining gtkmm since at least some time in 2001. That’s 14 years or so. Has any GNOME maintainer maintained one module for so long?

 

 

GTK+: Aligning / Justification in text widgets

There are 3 GTK+ text widgets: GtkEntry, GtkTextView, and GtkLabel. I noticed recently that they are a little inconsistent in how they offer alignment of their text, and the API confuses the terms justification and alignment slightly. This is highly unlikely to change, because that would be disruptive to existing code, but maybe this is helpful to people trying to use the API as it is now.

I’ve put some test_gtk_text_widgets_align.c example code in github. It shows two GtkLabels (single-line and multi-line) two GtkTextViews (single line and multi-line) and a GtkEntry (single-line only). I tried this with GTK+ 3.15.9. I’ve mostly ignored deprecated API, such as GtkMisc and GtkAlignment, to simplify things.

I’ve referred to the API via the *_set_*() functions, but this API is available as properties too. There are also vertical equivalents though I only talk about horizontal alignment here.

Default

This is how it looks by default. It looks fine, though the GtkLabel, and only the GtkLabel, defaults to center alignment – not a very useful default.

Justification

Now, if you want to justify the text to the right, you might call gtk_label_set_justify() on the GtkLabels and call gtk_text_view_set_justification() on the GtkTextViews, though you’ll need to call gtk_text_view_set_wrap_mode() for that to take effect. Then you’d see something like the screenshot below.

You’d notice

  • The justification had no effect on the single-line GtkLabel (as per the gtk_label_set_justify() documentation) but it did have an effect on the single-line GtkTextView.
  • The text in the GtkLabel remains aligned in the center (the GtkLabel default) even though it’s justified within that central part.
  • We didn’t call any justification method on the GtkEntry, because it has none. However, see below about gtk_entry_set_alignment().

Justification and Alignment

To fix that center-alignment of the right-justified text in the GtkLabel, you could call gtk_widget_set_halign(). Then you’d see this:

But, strangely:

  • The center-aligned right-justified text in the multi-line GtkLabel is unchanged. It remains center-aligned – it is not flush with the right side of the widget. But see below about gtk_label_set_xalign().
  • The single-line GtkLabel now appears to be justified/aligned to the right, which is nice. But see below.
  • The GtkTextViews have changed their word wrapping for some reason. I have no idea why.
  • The GtkTextViews and GtkEntry now use only just enough space at the right for their entire widgets, not just the text that they contain. In fact, the GtkEntry is now too small to show all of its text and, strangely, that happens even if I use gtk_widget_set_hexpand() on the GtkEntry.

This shows us that gtk_widget_set_halign() affects the whole widget (as per the halign documentation), not just the text. That is more obvious if we set a background color. Then we see that that’s why the single-line GtkLabel now looks justified – it’s really just the whole widget that has been aligned to the right:

Obviously, I don’t want this effect with the GtkTextViews, and it would only be useful on a single-line GtkLabel. Luckily we don’t need to use gtk_widget_set_halign() at all to justify text:

gtk_label_set_xalign

The GTK+ developers noticed this problem with GtkWidget’s halign so in the very latest GTK+ (3.15/3.16), they added gtk_label_set_xalign(). This aligns the text in the GtkLabel, rather than the GtkLabel itself. Like so:

I just pushed an improvement to the gtk_misc_set_alignment() deprecation documentation to make that clearer.

gtk_misc_set_alignment (deprecated)

If you can’t use the last GTK+ API, you can use the deprecated gtk_misc_set_alignment() method to get the same effect as gtk_label_set_xalign(). (Ignore the GtkTextViews here – they don’t derive from GtkMisc).

screenshot_test_gtk_text_widgets_set_alignment

Entry alignment

Likewise, GtkEntry has gtk_entry_set_alignment(), which has been in GTK+ since 2.4. Like gtk_labeL_set_xalign(), it affects the text in the widget, not widget itself.

screenshot_test_gtk_text_widgets_entry_alignment

Conclusion

So, if I wanted to justify my widget’s text, without changing the size of the widget itself, I’d decide what to do like this:

  • For a GtkLabel: Use both gtk_label_set_xalign() and gtk_label_set_justify(). Use gtk_misc_set_alignment() instead of gtk_label_set_xalign() if you can’t use GTK+ 3.16.
  • For a GtkTextView: Use gtk_text_view_set_justification() with gtk_text_view_set_wrap_mode().
  • For a GtkEntry: Use gtk_entry_set_alignment().

I could be wrong, so do please tell me how.

Locking down a GNOME setting

I think the dconf documentation and GNOME’s Sysadmin lockdown documentation (There’s this GNOME dconf wiki page too) could be clearer as well as being less duplicated and scattered. I’ve started trying to improve those documents directly.

In the meantime, here are some simple instructions for locking down some settings in GNOME 3 so the user cannot change them. Thanks to Ryan for explaining this to me. I’d welcome anyone’s extra corrections.

In this example, two children, Alice and Bobby, have user accounts on the computer called “alice” and “bobby”, and I want their accounts, and only their accounts, to not allow changing the list of application launchers in gnome-shell’s Dash, and not allow changing the desktop background. (Just as an example.)

Creating a dconf profile

I create a dconf profile for children in /etc/dconf/profile/, like so:

$ sudo nano /etc/dconf/profile/child

And I put this text in that file:

user-db:user
system-db:child

That tells dconf to use the “user database” named “user” as the writable store of settings for this dconf profile. Whatever database is on this first line will be used as the writable database. “user-db” (user database) just means that dconf should look in XDG_CONFIG_HOME/dconf for this database. That typically means ~/.config/dconf/, so this is specific to the user. This is what dconf uses by default if you haven’t assigned a dconf profile or changed the default “user” profile.

This example additionally tells dconf to use our “system database” named “child” for this dconf profile. Because this is not on the first line it is not writable. Because it’s a “system database” it will be in a shared location – typically /etc/dconf/db/. So this is a good place to specify some locks to prevent changes in the “user database” by anyone with this “child” profile. We could also use this “system database” to set some default values for the “child” profile.

The dconf overview documentation explains that profile file format more fully.

Creating a dconf lock file

Then I create a lock file for that “child” system database, like so, though the actual filename doesn’t matter:

$ sudo mkdir /etc/dconf/db/child.d
$ sudo nano /etc/dconf/profile/child.d/locks/00_some_locks

I put this text in that lock file:

/org/gnome/desktop/background/picture-uri
/org/gnome/shell/favorite-apps

I then call “dconf update” to tell it about the new profile and the lock file:

$ sudo dconf update

However, when you change the lock file, you’ll often need to do this too to make “dconf update” notice (see dconf  bug #741437):

$ sudo touch /etc/dconf/profile/child.d/locks
$ sudo dconf update

Using the dconf profile

Then I assign that dconf profile to the children’s user accounts, for instance by setting the DCONF_PROFILE environment variable in Alice’s .profile file:

$ sudo mkdir /home/alice/.profile

like so:

export DCONF_PROFILE="child"

If the child is already logged in then she’ll need to log out again to make her account use the new dconf profile. Also, don’t be foolish like me and put that in the .bash_rc file instead. That way lies confusion.

Note that the Alice can change her DCONF_PROFILE by changing that .profile file, to avoid the locks in her current profile. Or she can add a .bash_profile file to override .profile, or do something else clever. Locking of dconf settings is only for convenience – it isn’t meant to provide security. So if the user knows how to change her DCONF_PROFILE, she should probably be allowed to.

It would be nice if there was some GUI for managing profiles, and the databases’ locks, and default values. That seem doable.

I also wonder if there could be any API for applications to ask for admin access before making changes. Then a parent could, for instance, add just a single application launcher to the Dash. But I guess that would need us to either remove the dconf profile from the user (which needs a logout and login) or would need us to remove the lock from the dconf profiles’ system database, which would briefly unlock the setting for all other users who have the same dconf profile.

android-galaxyzoo: Superficial porting to Android 5.0 (Material design)

Here are some notes about my experience adapting android-galaxyzoo to Material design for Android 5.0 (Lollipop) though I only used the most superficial parts of Material design.

AppCompat v21

Android 5.0 (Lollipop) has a new UI theme and some new APIs. However, for the next few years, almost everyone will use the slightly awkward AppCompat v21 compatibility API instead to achieve most of the same behavior on older devices too. Chris Banes wrote up a nice overview of AppCompat v21, some of which I mention here again for completeness.

I’m using Gradle, as should you, so I added this to the dependencies block in my app/build.gradle file. You’ll want to use the latest version.

compile "com.android.support:appcompat-v7:21.0.3"

Theme

First, I switched from the dark Holo theme to the (AppCompat) dark Material theme by changing the parent theme in my styles.xml. See the Toolbar section below about the use of the “.NoActionBar” versions of these themes.

- <style name="AppTheme" parent="android:Theme.Holo">
+ <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">

If you were using the light theme, that would be:

- <style name="AppTheme" parent="android:Theme.Holo.Light">
+ <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

Note that we don’t use the android: prefix with the AppCompat theme, because the theme is being bundled directly into our app via the appcompatv21 library.

I then specified  the standard colorPrimary and colorAccent colors along with some more shenanigans to get the right text and icon colors in my toolbar.

I also used the TextAppearance_AppCompat_* widget styles instead of the regular textAppearance* style attributes, because it’s recommended in the Typography section of this official “Implementing Material Design in Your Android app” blog entry. However, I didn’t notice any difference in appearance, and I wonder why we wouldn’t just get the correct styles by just using the new overall theme.

I actually created a base style and two derived styles, to support Transitions – see below.

Toolbar

The new Toolbar widget replaces the ActionBar, though the documentation doesn’t actually say that yet. Generically, they are called the “App Bar” in the Material Design document. I’m not sure that I really got any benefit from using it because my App Bar doesn’t do anything special, but I wanted to use the latest API.

To use Toolbar instead of ActionBar,  you should derive from the .NoActionBar version of the theme, such as Theme.AppCompat.NoActionBar, though I used the regular Theme.AppCompat for a long time without noticing any difference.

Then you’ll want to add a Toolbar widget to the Layout XML files for every activity. I did that by creating a toolbar.xml file

<?xml version="1.0" encoding="utf-8"?>

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/color_primary">
</android.support.v7.widget.Toolbar>

and then I just including that from all the activity layouts like so:

<include layout="@layout/toolbar" />

I also specified the app:theme and app:popupTheme to get the right text and icon colors in my toolbar.

To use this toolbar as the App Bar, you need to derive from ActionBarActivity and call its setSupportActionBar() method. I did that in a utility function, like so:

Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar);
activity.setSupportActionBar(toolbar);

RecyclerView

Android 5.0 adds the RecyclerView widget, available for older API levels via the support.recyclerview library. For instance, I added this to the dependencies block in my app/build.gradle file. You’ll want to use the latest version.

compile 'com.android.support:recyclerview-v7:21.0.0'

RecyclerView apparently replaces ListView and GridView, though the documentation doesn’t yet actually say that, adding confusion for new developers. I replaced my use of GridView with RecyclerView to get support for simple Material Design transitions.

Unfortunately, RecyclerView has no real cursor support, so it’s hard to use it to view data from a ContentProvider. This is particularly annoying because the API of ListView and GridView previously pushed us towards moving code into a ContentProvider. My own Cursor-based RecyclerView.Adapter is terribly inefficient and totally unsuitable for a large number of items.

There’s an awful lack of practical documentation or example code for RecyclerView, even for simple tasks like responding to a click. Until there’s an easier way, you’ll need some tedious boilerplate code to derive your RecyclerView.ViewHolder from View.OnClickListener and call setOnClickListener() on one of your child views.

Transitions

I wanted the typical move-and-scale transition that we see in Material Design apps, so that clicking on one of many items makes its image expand and move into the subsequent detail activity, and shrink back again when you go back.

To achieve this, I had to specify various settings in my theme, but only Android 5.0 (Lollipop) devices support these transition items, so I created a base theme in res/styles.xml, and derived from it:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="AppTheme" parent="AppTheme.Base" />

    <style name="AppTheme.Base" parent="Theme.AppCompat.NoActionBar">
        <item name="colorPrimary">@color/color_primary</item>
        ...

I then created a styles.xml file just for API Level 21, by putting it in res/v21/styles.xml, where I derived from the base theme again:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        <item name="android:windowContentTransitions">true</item>
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>

        <!-- specify shared element transitions -->
        <item name="android:windowSharedElementEnterTransition">
            @transition/change_image_transform</item>
        <item name="android:windowSharedElementExitTransition">
            @transition/change_image_transform</item>
    </style>
</resources>

I then defined that change_image_transform transition in my res/transition/change_image_transform.xml file, like so:

<?xml version="1.0" encoding="utf-8"?>
<transitionSet>
    <changeBounds/>
    <changeImageTransform/>
</transitionSet>

To actually use this transition on images, I needed to specify the android:transitionName on the two ImageViews in the the layout XML files for the two Activities (Fragments in my case).

Mostly this was all voodoo which I put together gradually after finding clues scattered around the internet. I haven’t found a good official example that shows this.

Unfortunately, the transition doesn’t seem to work when the user presses the Up button on the toolbar instead of using the standard Back button, even though that’s indistinguishable from Back for most users in most activities.

Metrics and Keylines

I made a fair effort to adapt my margins and padding to fit in with the Material Design Metrics and Keylines, which wasn’t too hard.

Unfortunately, the standard Android Button’s appearance is just as usless for Material design as it was for the Holo theme. It has a fake margin around its inside edges, which is part of its background graphic rather than any adjustable margin or paddng property.

So, to make the button’s sides actually flush with other widgets, and to position them properly on the layout grid, I had to specify a custom background image or color. But then I lost the nice Material Design ripple effect. I hope someone knows how to do this properly.

Activity classes without Toolbar support

There are a few helpful derived activity classes, such as AccountAuthenticatorActivity and PreferenceActivity, but these haven’t been changed to derived from ActionBarActivity, so you can’t call setSupportActionBar() on them. They can’t be changed without breaking compatibility, so you’ll have to reimplement them in your code. It’s not a lot of code but it’s an unpleasant developer experience.

 

 

android-galaxyzoo: Network I/O and UI responsiveness

While developing the Galaxy Zoo app for Android, I experienced problems with UI responsiveness while the app was downloading from, or uploading to, the remote server. I don’t mean just the usual problems caused by doing network I/O or file system access in the UI thread – mistakes that can often be caught by using Strict Mode. I mean that buttons didn’t respond to presses if the app happened to be doing I/O in an AsyncTask.doInBackground().

I solved this problem, but it was an incredibly frustrating journey. These notes might help the next person. So many Android apps are just a fancy way to interact with a website’s data, caching it locally, but the regular Android API doesn’t make that easy enough.

My app uses a ContentProvider, because the Android API seems to point us towards doing so, as I found while creating my experimental Android Glom app. The ContentProvider usually runs in the same process (and thread) as the main UI, so I don’t think this architecture was a cause of the UI responsiveness problem.

Thread+ResponseHandler versus AsyncTask

My ContentProvider needed to communicate with the remote server via REST messages, downloading images from the URLs that it then discovered and caching those images locally as well as storing data in its SQLite database. At first, I used the Thread class directly, with a UriRequestTask class derived from Runnable, that used HttpClient and accepted a (HttpClient) ResponseHandler. This was based on the example code in O’Reilly’s Programming Android (2nd Edition) book, in its “A Content Provider as a Facade for a RESTful Web Service” chapter (which you can see some of here).

Later, before I found the UI responsiveness problem, I replaced this Thread and RequestTask idea with AsyncTask because that seemed more robust and made it easier to get a result back to the main thread. I didn’t understand why the “Programming Android” book didn’t use AsyncTask in its ContentProvider. Yet later, I found that Strict Mode didn’t allow that use of AsyncTask in a SyncAdapter’s non-UI thread on some older devices (API version <15), causing an ExceptionInInitializerError with “Can’t create handler inside thread that has not called Looper.prepare()”. Maybe the authors found the same problem.

HttpURLConnection instead of HttpClient

Incidentally, I later realized that the Android developers now discourage use of HttpClient, because their version of HttpClient is buggy and they can’t update it without breaking compatibility. So I changed from HttpClient to HttpURLConnection (and here and here). Luckily, this fixed the endless redirect problem I (like others) was having with my uploads.

Again, I felt led astray by the “Programming Android” book, but books get out of date very quickly and the Android documentation apparently gives us new clues only reluctantly. Hopefully the 3rd edition will improve this.

Avoiding the user

This is when I noticed the UI responsiveness problem. I tried using Thread directly in various ways instead of AsyncTasks, fearing my own changes had caused it, but it made no difference.

I tried all kinds of tricks to avoid doing any I/O, even in the AsyncTasks, when the user was likely to be using the UI, trying to wait until it seemed that the user was idle and then doing some quick I/O before getting out of the way again. But the user is unpredictable and would still try to press a button now and then exactly when my app was doing some sneaky I/O.

After lots of imprecise testing, I was fairly sure that the problem was worse when the app happened to be doing some filesystem I/O, even just writing to the SQLite database, but it was definitely caused too by doing network I/O of even small JSON files. We should expect disk I/O to be worse than network I/O, of course.

SyncAdapter

I wanted to learn about Android’s SyncAdapter framework anyway, so I spent a week figuring that out despite its awful hand-wavy documentation. Luckily, it fixed the UI responsiveness problems. I think it helped partly because the I/O was now in a separate process, though that doesn’t feel like it should be necessary. Also, the SyncAdapter framework can decide when best to let the SyncAdapter do its work, based on the whole system. Presumably it can then prevent unrelated processes from making the UI responsiveness even worse.

Unfortunately, using SyncAdapter does mean that I lose control over when I may download items in advance. For instance, I often find that a new install of the app doesn’t fill up its initial list of ten items until five or ten minutes after the first start. In the meantime, the app requests the items directly when necessary. I call ContentProvider.requestSync(), with SYNC_EXTRAS_MANUAL, when I’m sure there’s work for the SyncAdapter to do, but it just seems to take this as a suggestion that it’s free to ignore.

Authenticator and Account

To use the SyncAdapter, I had to create an Authenticator, for which I needed an Account type, even if you are accessing your server anonymously. This account type will show up in the Settings->Accounts UI. Presumably this is why some other apps show up in the Accounts Settings, even though they don’t need any login. Maybe they are doing it just so they can use SyncAdapter.

SyncAdapter versus SharedPreferences/PreferenceFragment

So I started by storing the login details via the AccountManager instead of via SharedPreferences. I later discovered that the app’s SharedPreferences (such as how many items to download) were unavailable to the SyncAdapter’s separate process. That is documented as “currently this class does not support use across multiple processes“. So I later put other preferences in the account too. Unfortunately, the standard settings/preferences UI only uses SharedPreferences, so I have hacky code to keep the SharedPreferences and the Account in sync – see my onSharedPreferencesChange() override in my PreferenceFragment, so the account’s UserData is changed when the standard settings UI is used, via my hacky copyPrefToAccount method.

AccountManager versus main/UI thread

I also later found that you can’t use the AccountManager API from the main UI thread even though the documentation says things like “It is safe to call this method from the main thread”. The Firefox on Android developers discovered this too (1, 2, 3). So I moved that code to an AsyncTask (for example). If you don’t then you’ll get StrictMode exceptions at least on API level 15 and 16 – maybe others. StrictMode seems to have been on for Android Honeycomb, and some users seem to enable StrictMode, so you will see this as crash reports on some devices.

Volley

I also wanted to try out the Volley library. This isn’t an official part of the Android API. For instance, there’s not even an official way to add it as a dependency – I used the Volley package that mcxiaoke helpfully published to maven central. But Google use Volley in some of their own apps and they recommend Volley in the Android documentation. The video linked from there is well worth watching.

When I rewrote my HttpURL Connection-using code with Volley it seemed to make my downloads noticeably faster, probably because it avoids doing I/O in too many threads simultaneously. This was an easy win.

I couldn’t use Volley for my uploads, unfortunately, because Volley uses HttpClient on older Android versions whose HttpUrlConnection wasn’t good enough yet, causing the old endless-redirect problem again. So I use HttpURLConnection directly for that.

Picasso

I also switched to using Picasso to fill ImageViews with bitmaps from our ContentProvider or directly from the internet, instead of my own AsyncTask. This simplified the code and gave me some extra caching, particularly simplifying my ListView/RecyclerView adaptor that previously had its own custom LruCache. For instance 1, 2, 3. Image loading just generally felt much faster everywhere that I used Picasso, though I don’t know exactly why.

Just filling an ImageView without blocking the UI seems like something unexciting that the Android API should already make easy.

Galaxy Zoo for Android

I just released my Galaxy Zoo android app to the Google Play store. The Zooniverse team have adopted it as their official Galazy Zoo app for Android.

Like the Galaxy Zoo website, it asks you questions about a picture of a galaxy, with each question depending on the previous question. This “Citizen Science” helps astronomers to analyze the huge amount of images of galaxies provided, for instance, by the Hubble Space Telescope. There are several other Zooniverse projects, though most require more thought and have more complicated user interaction.

screenshot_nexus4_api21_classify_first screenshot_nexus4_api21_list

I have already released several beta versions to a handful of helpful testers, but now I’m nervous about it being publicly available. I’d rather not be bombarded with one-star reviews if there’s a bug I haven’t caught yet or if people don’t like something about the questions themselves.

There was a previous Galaxy Zoo android app that I think was in use until around 2012, but it stopped working with the latest version of the server and apparently wasn’t updated. It’s no longer available from the Google Play store. This new Galaxy Zoo android app is open source on github, so it should have more future. For instance, that would let other developers investigate problems if there are server changes, even if I don’t (though I would). Patches and pull requests are very welcome. There are even a few minor issues that I’d already like help with.

I’ve been working on this for the past few weeks, using it as a real-world exercise to learn about Android development, trying to do everything properly. I’ve enjoyed diving into something new, and it feels good to have gained the experience. However, Android development ultimately feels just as awkward as every other development environment I’ve ever worked with – no more nor less. I’ll write some follow-up blog entries about the technical parts of the adventure.