Google TV – Part 3

May 18th, 2012

In the previous article we explored some of the difference in developing for Google TV compared to the Android phones and tablets that we’ve become accustomed to. In this concluding article in this series, we’ll have a look at some UI & UX considerations that we need to take in to account when designing apps for Google TV.
Read the rest of this entry »

Google TV – Part 2

May 11th, 2012

In the previous article we got an overview of Google TV and some of the features which offer developers the potential to create some interesting apps. In this article we’ll look at some of the differences between developing for Google TV compared to the Android phone and tablet devices that we’ve become used to.
Read the rest of this entry »

Google TV – Part 1

May 4th, 2012

Recently those nice folks at Google sent me a Logitec Revue which implements Google TV. Having played with it for a few weeks here are some initial thoughts about how best to design your UI / UX for this platform.
Read the rest of this entry »

More Vector Drawables – Part 2

April 27th, 2012

In the previous article we looked at a tiled background pattern. In this article we’ll look at how we can create a panel with a 3D effect border created using a vector drawable.
Read the rest of this entry »

More Vector Drawables – Part 1

April 20th, 2012

In recent articles on Styling Android I have diverged a little from pure UI and covered some more subtle aspects to improve your UX. In this series we’re going to return to something that was covered in the very first post to Styling Android: Vector Drawables. Previously we have looked at how vector drawables can be used instead of bitmaps to provide better scaleability of your UI components between different devices & from-factors. In this series we’ll look at some further tricks that you can use to get the most out of vector drawables.
Read the rest of this entry »

Memory Cache – Part 4

April 13th, 2012

In the previous part of this series we implemented a simple memory cache based upon WeakReference. It certainly improved performance when we were using the same image multiple times within a short period, but it is easy to predict that our cached images would not survive an intensive operation, such as an Activity transition. Also, the policy of when to free cached items was completely outside of our control. While there are certainly use-cases where this is not an issue, it is often necessary to have rather more control. In this article we’ll look at LruCache which gives us precisely that.

LruCache cache was introduced in API level 12 (3.1) but is available through the Support Library back to 1.6. It is a generic class which we can strongly type when subclassing it:

public class LruMemoryCache extends LruCache<String, Bitmap>
{
	private final Context context;

	public LruMemoryCache(Context context)
	{
		super( 10 );
		this.context = context;
	}

	@Override
	protected Bitmap create( String key )
	{
		return Utils.loadAsset( context, key );
	}
}

We’ve defined a cache which will use String keys to index Bitmap objects, much the same as we did in the previous part of this series. The implementation is actually pretty straightforward: In the constructor we call the constructor of the base class to set the size of our cache to 10 items; and we override create which calls the utility method that we defined in part 2.

Using this cache is even simpler still. We first create an instance of our cache:

lruMemCache = new LruMemoryCache( getApplicationContext() );

and then obtain items using the get() method:

Bitmap bitmap = lruMemCache.get( ASSET_NAME );

So, how does it work? LruCache maintains a list of cached items (in our case we defined a cache size of 10, so this list will be up to 10 items). Whenever we try and access a specific item, it tries to find it in the cache. If the item already exists, it is moved to the head of the list, and returned. If the item does not exist, then our create() method is called to create a new instance, and this is added to the head of the list before being returned. As a new item is added to the list LruCache checks whether the addition would cause the list to exceed the size that we declared earlier. If not, then it simply adds it, but if so it first deletes the item at the tail of the list. Thus we now have a cache which is not controlled by garbage collection, and which is optimised to keep the frequently accessed items in the cache.

So, how we’ve got some pretty useful functionality in just a few lines of code, but LruCache gives us more. Images can be tricky beasts because they vary in size quite significantly. Holding an arbitrary quantity of images (i.e. 10 in our example) can result in the total size of the cache varying quite enormously depending on the sizes of the individual images. So what if we want to limit the memory usage of our cache? LruCache allows us to override the way that the cache size is calculated. We do this by first changing how the size of each cached item is calculated:

@Override
protected int sizeOf( String key, Bitmap value )
{
	return value.getByteCount();
}

The default implementation of sizeOf() simply returns 1, so this provides the default behaviour that we have already seen with a satic number of items. We have overridden this to return the size of the bitmap instead.

Next we need to change how we specify the size of our cache by changing the constructor:

public LruMemoryCache(Context context)
{
	super( 5 * 1024 * 1024 );
	this.context = context;
}

Here we are specifying a maximum cache size of 5MiB. Whenever the cache exceeds this, items will be evicted from the tail until the size drops below 5MiB once again. We can actually do whatever we want provided that we match the units that we’re using in the constructor to specify the maximum size, to those used in our sizeOf.

This is a much better cache implementation. It gives us greater control and cached items will potentially last much longer than the next GC.

Remember to clear your cache if memory is running low. If onLowMemory() is called on your Activity, it is much better to call evictAll() on your cache and allow it to be rebuilt than it is for your app to crash with an OutOfMemoryError!

LruCache can also be used to manage a cache on the SD card. Rather than storing bitmaps in the cache, you can store File objects instead, calculate the size using file.length(), and override entryRemoved() in LruCache to delete the physical file on the SD card when its File is evicted from the cache.

That completes our look at caching. Hopefully you will have a better understanding of some of the tools available to help you to select the correct approach to meet your caching requirements.

The source code for this article can be found here.

Memory Cache – Part 3

April 6th, 2012

In the previous part of this series we looked at why caching images may help the performance of our app, so let’s firstly look at a technique for creating a short-lived cache. The items in the cache will only survive until the next GC if they are not strongly referenced, but this can sometimes be desirable if we want to be extremely conservative with resources.
Read the rest of this entry »

Memory Cache – Part 2

March 30th, 2012

In the previous article we looked at the theory behind weak references. In this article we’ll look at one use-case where a simple memory cache may speed things up.

First let’s put together a basic project to do this. We’ll create a new 2.3.3 project called MemoryCache including an Activity named MemoryCacheActivity, and modify main.xml to contain two ImageView objects wrapped in a LinearLayout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="100dp"
        android:layout_height="100dp"/>

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="100dp"
        android:layout_height="100dp"/>

</LinearLayout>

Next we’ll put an image in to the assets folder of our project .You can download the Styling Android logo from here.

Next we’ll create a utility class named Utils which will contain a single static method:

final class Utils
{
	private static final String TAG = MemCacheActivity.TAG;

	public static Bitmap loadAsset( Context context,
		String assetName )
	{
		Bitmap bitmap = null;
		InputStream is = null;
		try
		{
			is = context.getAssets().open( assetName );
			bitmap = BitmapFactory.decodeStream( is );
		} catch (Exception e)
		{
			Log.e( TAG, "Load Error", e );
		} finally
		{
			if (is != null)
			{
				try
				{
					is.close();
				} catch (Exception e)
				{
				}
			}
		}
		return bitmap;
	}
}

We’ll use this method a number of times, so we define it here as a static to make life easier later on.

You may be wondering why we are loading the image from assets and not simply including it as a drawable and loading it through the Resources. The reason for this is that Android itself employs some caching as part of the resources infrastructure, so you are already getting the benefit of memory caching. This will not be used when you obtain images from other sources, so we are loading from assets to simulate an alternate source.

Now we’ll change our MemoryCacheActivity:

public class MemCacheActivity extends Activity {
	public static final String TAG = "MemoryCache";
	public static final String ASSET_NAME = "sa.png";

	private ImageView imageView1 = null;
	private ImageView imageView2 = null;
	private MemoryCache memCache = null;

	@Override
	public void onCreate( Bundle savedInstanceState )
	{
		super.onCreate( savedInstanceState );
		setContentView( R.layout.main );

		imageView1 = (ImageView) findViewById( R.id.imageView1 );
		imageView2 = (ImageView) findViewById( R.id.imageView2 );

		loadManual();
	}

	private void loadManual()
	{
		TimingLogger tl = new TimingLogger( TAG, "Standard image loading" );
		imageView1.setImageBitmap( Utils.loadAsset( this, ASSET_NAME ) );
		tl.addSplit( "first" );
		imageView2.setImageBitmap( Utils.loadAsset( this, ASSET_NAME ) );
		tl.addSplit( "second" );
		tl.dumpToLog();
	}

In our onCreate() we are setting the content view the main.xml which we defined earlier, getting references to the two ImageViews that we declared in our layout, creating an instance of our MemoryCache, and calling loadManual(). loadManual() will simply set the images on each of our ImageView objects by loading the bitmap twice using the utility method from MemoryCache.

If you haven’t encountered TimingLogger before, it is an extremely useful tool for performance monitoring in your app. You simply create a TimingLogger instance using a TAG similar to android.util.Log and a text description. You then call addSplit() with a text description repeatedly at various points within your code, and finally call dumpToLog() which will output all of the gathered information and split times to logcat. One thing that you must do is to set the log level to Verbose otherwise nothing will be output. This can be done in various ways as detailed here, but we’ll use:

adb shell setprop log.tag.MemoryCache VERBOSE

If we run this we see the following:

Memory Cahe

The working app

More importantly, we’ll get the following in our log:

Standard image loading: begin
Standard image loading:      114 ms, first
Standard image loading:      92 ms, second
Standard image loading: end, 206 ms

Out TimingLogger output shows us that both images are taking around 100ms to load, for a combined time of around 200ms. There will be some minor variations in image load times throughout our testing.

While this may seem rather trivial it could be come more of an issue if we are using large images which are going to take longer to load, or if we re-use the same image man times. In the next part of this series we’ll have a look at implementing a simple memory cache to make things a little more efficient.

The source code for this article can be found here.

Memory Cache – Part 1

March 23rd, 2012

Previously on Styling Android we have discussed how important it is to make your app as fast as possible because making your user wait for things to happen is a sure way to drive them away from your app. Also, you have to be quite careful when it comes to using images within your app because images tend to be relatively large and even minor inefficiencies in image handling can have a major impact on your app. In this series of articles we’re going to look at a technique of using a memory cache for images to avoid having to hold multiple copies of the same image in memory when that image is used multiple times in your layout.
Read the rest of this entry »

Background Tasks – Part 6

March 16th, 2012

In the previous article we discussed the Android Service architecture and looked at how to properly implement your Service to both behave well and avoid being killed by the OS or a TaskKiller. In this concluding article in this series well look at IntentService and look at ways that we can trigger UI updates from a Service.
Read the rest of this entry »