AsyncTask helpers [Android]

When using AsyncTask, there are two things I always end up doing: include some error handling and show a progress dialog while the task is executing. I made some little helper classes for that, that I now use instead of AsyncTask.  To use them, override the run, onSuccess and onFailure methods.

import android.os.AsyncTask;

/**
 * Helper class for AsyncTask that supports exception handling.
 *
 * @param <Params>
 * The type of parameter passed to the background handler.
 *
 * @param <Result>
 * The result returned by the background handler.
 *
 * @param <ExceptionType>
 * The kind of exception the background handler may throw.
 */
public abstract class AsyncHelper<Params, Result, ExceptionType extends Exception>
extends AsyncTask<Params, Void, AsyncHelper.ResultWrapper<Result, ExceptionType>>
{
	/// Wrapper around a result or exception
	static class ResultWrapper<Result, ExceptionType>
	{
		private Result result;
		private ExceptionType exception;

		private ResultWrapper(Result result, ExceptionType exception)
		{
			this.result = result;
			this.exception = exception;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	protected ResultWrapper<Result, ExceptionType> doInBackground(Params... args)
	{
		try
		{
			return new ResultWrapper<Result, ExceptionType>(run(args), null);
		}
		catch(Exception e) // Using generic ExceptionType in a catch block is not allowed
		{
			return new ResultWrapper<Result, ExceptionType>(null, (ExceptionType) e);
		}
	}

	@Override
	protected void onPostExecute(ResultWrapper<Result, ExceptionType> result)
	{
		if (result.exception == null)
			onSuccess(result.result);
		else
			onFailure(result.exception);
	}

	/**
	 * Performs the background task.
	 *
	 * @param args
	 * The parameters passed to execute.
	 *
	 * @return
	 * The return value, passed to onSuccess.
	 *
	 * @throws ExceptionType
	 * An exception, passed to onFailure.
	 */
	abstract protected Result run(Params...args)
	throws ExceptionType;

	/**
	 * Invoked when the background task finishes successfully.
	 *
	 * @param result
	 * The result returned by run.
	 */
	abstract protected void onSuccess(Result result);

	/**
	 * Invoked when the background task thows an exception.
	 *
	 * @param exception
	 * The exception thrown by run.
	 */
	abstract protected void onFailure(ExceptionType exception);
}
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;

/**
 * A background task that shows a cancelable progress dialog while running.
 *
 * @param <Params>
 * The type of parameter passed to the background handler.
 *
 * @param <Result>
 * The result returned by the background handler.
 *
 * @param <ExceptionType>
 * The kind of exception the background handler may throw.
 */
public abstract class AsyncProgressHelper<Params, Result, ExceptionType extends Exception>
extends AsyncHelper<Params, Result, ExceptionType>
{
	protected final Activity source;
	protected final String title;
	protected ProgressDialog progress;

	/**
	 * Constructor.
	 *
	 * @param source
	 * The activity that is requesting the background task.
	 *
	 * @param title
	 * The title of the progress dialog.
	 */
	public AsyncProgressHelper(Activity source, String title)
	{
		this.source = source;
		this.title = title;
	}

    protected void onPreExecute()
    {
    	progress = ProgressDialog.show(source, null, title, true, true,
    			new OnCancelListener()
				{
					public void onCancel(DialogInterface dialog)
					{
						cancel(true);
					}
				});
    }

	@Override
	protected void onPostExecute(ResultWrapper<Result, ExceptionType> result)
	{
		progress.hide();
		super.onPostExecute(result);
	}
}

Like other code samples on this page, these are hereby released under the GPL.

| Filed in Android | Permalink | Comments(0) »

Adding check boxes to list views [Android]

Adding custom check boxes to a ListView in Android is simple: just use an item layout that includes a check box, such as a CheckedTextView or this one:

<TableLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:stretchColumns="0"
>
  <TableRow>
    <TextView
      android:id="@android:id/text1"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:paddingTop="10dip"
      android:paddingBottom="10dip"
      android:paddingLeft="15dip"
      android:textAppearance="?android:attr/textAppearanceSmall"
    />
    <CheckBox
      android:id="@android:id/toggle"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:focusable="false"
      style="?android:attr/starStyle"
    />
  </TableRow>
</TableLayout>

Getting it to work well is a bit tricky though. One thing to keep in mind is to set android:focusable=”false” on the check box, to prevent it from stealing focus away from the list, thereby making it unclickable. But what took me longest to figure out is how to bind data to the check boxes. For example, let’s say you’re taking data from a database and one of the columns is a boolean that indicates if the item should be checked. The data is coming from a SimpleCursorAdapter, which supports binding columns to views using the ‘from’ and ‘to’ parameters in the constructor. However, this will give you check boxes with the string true or false next to it, as it binds the value to the check box’ label rather than the check mark.

So you’ll have to manually bind the check boxes to database values, using a ViewBinder. My first attempt was this, which indeed seems to set the check marks correctly.

adapter.setViewBinder(new ViewBinder()
{
	public boolean setViewValue(View view, final Cursor cursor, int column)
	{
		if (column == CHECK_COLUMN)
		{
			CheckBox checkBox = (CheckBox) view;
			checkBox.setChecked(cursor.getInt(CHECK_COLUMN) != 0);
			checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener()
			{
				public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
				{
					// Do something to update the check column
				}
			});
			return true;
		}
		return false;
	}
});

However, the moment you start scrolling and clicking, you’ll notice entries get checked or unchecked randomly. It took me a while to figure this out, but it is due to the ListView reusing the item views when scrolling. The OnCheckedChangeListener is still attached to the check box when it is reused, so the call to setChecked will trigger the old listener, causing wrong updates to the database.

My first attempt was to call setChecked after setOnCheckedChangeListener, but this causes the listener to be invoked with the already set value of the check box, which – depending on your application – may cause lots of superfluous writes to the database, or completely mess up your application.

The solution I’m using now is to signal that a view is reused and then ignoring the call to the listener. To do this, I put the id of the item in the check box’ tag and clear it just before the call to setChecked (in fact, I was already storing the id there for use in the listener, so the clearing is the only additional step). In the listener, I check if the tag is null, and if it is ignore the signal. So it looks something like this:

adapter.setViewBinder(new ViewBinder()
{
	public boolean setViewValue(View view, final Cursor cursor, int column)
	{
		if (column == CHECK_COLUMN)
		{
			CheckBox checkBox = (CheckBox) view;

			// This method may reuse a view, set the tag to null so this is detected
			checkBox.setTag(null);
			checkBox.setChecked(cursor.getInt(CHECK_COLUMN) != 0);
			checkBox.setTag(id);
			checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener()
			{
				public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
				{
					String id = (String) buttonView.getTag();
					if (id != null)
					{
						// Do something useful now
					}
				}
			});
			return true;
		}
		return false;
	}
});

And this works! It’s not the cleanest solution, but it does the trick. I just can’t help feeling there should be a better way to do this.

| Filed in Android | Permalink | Comments(0) »

Custom post types [WordPress]

As of version 3.0, WordPress added the possibility to have custom post types. This allows you to separate different kind of posts, for example into blog posts and news items. In a recent project I’ve used this extensively and found I had to google some things, so I’ll write a quick summary here.

So, let’s say you want to add a post type ‘news’. You have to register it (most likely from a plugin, but you can also do it from a theme), using register_post_type.

register_post_type('news', array(
	'labels' => array(...),
	'public' => true,
	'publicly_queryable' => true,
	'show_ui' => true,
	'query_var' => true,
	'rewrite' => array('slug' => 'news', ...),
	'capability_type' => 'post',
	'hierarchical' => false,
	'menu_position' => null,
	'taxonomies' => array(...),
	'supports' => array('title','comments', ...)
));

The ‘labels’ array contains some user-displayable strings to identify the post type. The ‘rewrite’ array contains URL-rewriting rules. You’ll most likely want to have the rule ‘slug’ => ‘news’ there, so you can have URLs of the kind /news/this_is_a_news_item. The ‘supports’ array allows you specify capabilities of the post type, e.g. to allow comments on the posts. In principle everything a normal post can do is supported, with the exception of sticky posts, but this should be fixed in version 3.1.

Using the posts

Now that you have additional post types, you have to use them somehow. You’ll probably want to extend you own theme to use them; luckily, this requires very little work. By default a post is rendered using the template single.php and this will also work for custom post types (though there may be some issues if e.g. you post expects there to be tags when there are not). All you have to do is get your posts to be in the loop somehow. You can do this by explicitly by running a query that contains a post_type parameter, or you can use one of the plugins that is available to create archive pages automatically (search the plugin directory for “custom post type”).

Tags and categories

Custom post types also support tags and categories, but it requires some additional work. For this you have to register a so-called taxonomy, which can either be hierarchical (for categories) or not (for tags). You register these using register_taxonomy and then specify the names in your call to register_post_type (in the taxonomies array).

register_taxonomy( 'news_tag', 'news', array(
	'hierarchical' => false,
	'update_count_callback' => '_update_post_term_count',
	'query_var' => false,
	'rewrite' => false,
	'public' => true,
	'show_ui' => true
) );

It is important to note that taxonomies apply only to a single post type, so you cannot mix tags on normal posts and custom posts.

Querying for specific tags or categories (known collectively as terms) is not very well documented, but it is simple. In your query just use “taxonomy=<taxonomy_id eg news_tag>” and “term=<tag or category’s slug>”

| Filed in WordPress | Permalink | Comments(0) »

Reflection and generics [Java]

Sometimes you encounter a situation where it would be useful at runtime to know the kind of class you’re dealing with. This used to be easy using reflection, but the introduction of generics made it all a bit more complicated. For example, you may know you have an instance of a List, but how do you find out what kind of elements it contains?

The first thing you need to know is that when presented with an object, you quite simply can’t at runtime. For example, if you have the following code

List<?> list = new LinkedList<String>();

the only way you can access the reflection information is to call

list.getClass()

which will give you the class for

LinkedList<?>

The reason for this is that more type information is just not available at runtime. All handling of generics is performed by the compiler. This is also why you can do things like (I’m not saying you should, I’m just saying you can):

List<String> stringList = new LinkedList();
stringList.add("String");
List<Integer> intList = (List<Integer>)(List<?>) stringList;
Assert.assertEquals("String", intList.get(0));

However, in all structural elements, such as Fields and Classes, the information is available and I’ll show you how to access it. For this I’ll develop the following function:

	/**
	 * Retrieves the class of a generic parameter.
	 *
	 * @param type
	 * The type containing a generic.
	 *
	 * @param base
	 * The base type declaring the generic parameter.
	 *
	 * @param index
	 * The 0-based index of the generic parameter in the declaration.
	 *
	 * @return
	 * The class object representing the actual type of the generic parameter.
	 */
	public static Class getGenericType(Type type, Type base, int index)

And you’d use it like this:

	class FieldTest
	{
		public LinkedList<String> stringList;
	}

	Field field = FieldTest.class.getField("stringList");
	Type type = field.getGenericType();
	Class genericType = ReflectUtil.getGenericType(type, LinkedList.class, 0);

Which will yield the String class. If you have a class, you can also use it to get the generic types of superclasses and interfaces.

So, to the code:

public class ReflectUtil
{
	/**
	 * Retrieves the class of a generic parameter.
	 *
	 * @param type
	 * The type containing a generic.
	 *
	 * @param base
	 * The base type declaring the generic parameter.
	 *
	 * @param index
	 * The 0-based index of the generic parameter in the declaration.
	 *
	 * @return
	 * The class object representing the actual type of the generic parameter.
	 */
	public static Class<?> getGenericType(Type type, Type base, int index)
	{
		Type result = getGenericType(type, base, index, new HashMap<TypeVariable<?>, Type>());
		if (result instanceof Class<?>)
		{
			return (Class<?>) result;
		}
		else if (result instanceof ParameterizedType)
		{
			return (Class<?>) ((ParameterizedType) result).getRawType();
		}
		return null;
	}

	/**
	 * Implementation helper.
	 *
	 * @param generics
	 * Binds TypeVariables to implementing types.
	 */
	private static Type getGenericType(Type type, Type base, int index, Map<TypeVariable<?>, Type> generics)
	{
		if (type instanceof Class<?>)
		{
			Class<?> cls = (Class<?>) type;

			if (cls.equals(base))
			{
				// Found it, but no generic information available
				return null;
			}

			// Try the superclass
			Type superClass = cls.getGenericSuperclass();
			if (superClass != null)
			{
				Type result = getGenericType(superClass, base, index, generics);
				if (result != null)
					return result;
			}

			// Try the interfaces
			for (Type iface: cls.getGenericInterfaces())
			{
				Type result = getGenericType(iface, base, index, generics);
				if (result != null)
					return result;
			}
			return null;
		}
		else if (type instanceof ParameterizedType)
		{
			ParameterizedType param = (ParameterizedType) type;

			// Collect the generic parameters
			GenericDeclaration genDecl = (GenericDeclaration) param.getRawType();
			TypeVariable<?>[] formals = genDecl.getTypeParameters();
			Type[] actuals = param.getActualTypeArguments();
			for (int i = 0; i < formals.length; ++i)
			{
				Type actual = actuals[i];
				if (actual instanceof Class<?> ||
					actual instanceof ParameterizedType)
				{
					// The actual is a class or a declared
					generics.put(formals[i], actual);
				}
				else if (actual instanceof TypeVariable<?>)
				{
					// The actual is a TypeVariable, resolve it.
					// As the subclass binds the formal parameter declared in a superclass, and superclasses
					// are evaluated after this, the actual value will be available if it is present.
					TypeVariable<?> typeVar = (TypeVariable<?>) actual;
					Type value = generics.get(typeVar);
					generics.put(formals[i], value);
				}
				else
				{
					throw new RuntimeException("Unexpected case" + type);
				}
			}

			if (param.getRawType().equals(base))
			{
				// Found it, return the actual value
				return generics.get(formals[index]);
			}

			// Evaluate the raw type, to collect superclass/interfaces
			return getGenericType(param.getRawType(), base, index, generics);
		}
		else
		{
			throw new RuntimeException("Unexpected case: " + type);
		}
	}
}

The first thing to note is that the implementation is just a wrapper around a helper function that takes an additional map of types. This is done to handle cases such as the following (simplified) example:

class LinkedList<E>
implements Collection<E>
{
}

So, if you want to get the value of parameter E for the Collection, you have to look at the declaration of the LinkedList. The map records the mapping of these actual classes onto formal declarations, or TypeVariables as they are known in Java. The helper function performs this mapping as follows.

If the current type is a Class, then no generic information is available on it, so if it is the requested base type, it returns null. However, generic information is available on the superclasses (from now on, read “and interfaces” when I mention superclasses), so the superclass is evaluated recursively. This can be either another Class, in which case again no information is available, or a ParameterizedType, which is where it gets interesting. This records both a generic type and a set of actual parameters to that type. For example, if you have Map<String, Integer>, the ParameterizedType’s raw type is Map and its actual type argument is an array containing the String and Integer types.

It gets a bit more complicated in the LinkedList example described above, as the ParameterizedType contains a TypeVariable. In this case the map is used to retrieve the actual value of the parameter. To make this possible, any generic variable that is encountered is stored in the map with its actual type.

Note that the class above works for my purposes and may (read: will) still contain bugs. If I ever get around to writing unit tests for cases that I’m not using, I’ll update this post. The code in this post is hereby released under the GPL.

| Filed in Java | Permalink | Comments(0) »