Google TV

Supercharge your Google TV Android Apps

(Hardware Acceleration and Asynchronous Downloads)
Bhavya Vanaja, Christian Kurzke - Google TV Developer Relations

  1. Overview
  2. Why do we need Hardware Acceleration?
  3. Hardware Acceleration and Slide Transitions
  4. SlideShow using Alpha Animation
  5. Asynchronous downloading of bitmaps using ExecutorService
  6. Caching the images for faster launching
  7. Known Problems
  8. Summary

Overview

When we watch television, we have become accustomed to highly refined, professional graphics and smooth, fluid transitions between scenes. This article describes how developers can create outstanding Google TV applications with polished visual effects. For an in-depth description of general Android Hardware Accelerated graphics also read the Blog post by Romain Guy: Android 3.0 Hardware Acceleration.

Why do we need Hardware Acceleration?

All Google TV devices support the Android OpenGL ES 2.0 APIs. Those APIs give the developer direct access to the underlying Graphics Processor, and allow to create high performance 3D views. Those APIs are powerful but require some knowledge of OpenGL and 3D programming.

Android also has a regular "2D" Graphics API, which are much easier to use to display things like Images or render ListViews etc. A smooth transition between screens adds a lot of visual polish any app, from a simple slide show application to a music player transitioning between artist information cover art. Because TVs have a very high resolution display (up to 1920 x 1080 pixels) any full-screen transitions can be rather CPU intensive and may cause choppiness in the transition.

Since the Android 3.2 (Honeycomb) Software update for Google TV, those 2D APIs can now optionally use the high performance OpenGL engine to perform COU intensive drawing operations by taking advantage of the Hardware Acceleration for the Android animation framework.

Another frequent problem is that developers need to load a large number of thumbnails from a server. There is some convenient Android APIs for this, like the AsyncTask class. In this example we show how you can achieve even higher performance by using the Java Executor framework.

Hardware Acceleration and Slide Transitions

Hardware acceleration results in smoother animations, smoother scrolling, and overall better performance. If you are running an Animation in your application, you can enable hardware-accelerated rendering by setting android:hardwareAccelerated = "true" in your manifest's <application> element or for individual <activity> elements. At runtime you you can also disable the hardware acceleration for individual views. This granularity can be helpful if some parts of your application are more graphics intensive than others, and you want to avoid re-testing the entire application. The following snippet enables hardware acceleration at the activity and application levels.

Activity level:

<activity android:hardwareAccelerated="true" ... >

Application level:

<application android:hardwareAccelerated="true" ... >

View Level:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

SlideShow using Alpha Animation

Android defines a set of animation classes to easily create transitions like scale, rotate, move or fade-in or out of Views. In this example we use Alpha-Level animations which are generally used to fade-in and out objects. The "Alpha Level" of an object indicates how "transparent" an object is when it is drawn on screen. The value is specified as a float from 1.0 (meaning fully opaque) to 0.0 (which is fully transparent).

Animations can be defined either in XML or dynamically at runtime via APIs. Following is a sample snippet to show fade in and fade out transitions between two images during the slide show. This code can be found in the example code class SlideShowActivity method playAnim().

AlphaAnimation mFadeOutAnimation = new AlphaAnimation(1.0f, 0.0f); 
mFadeOutAnimation.setStartOffset(3000);
mFadeOutAnimation.setDuration(3000);
mFadeOutAnimation.setFillAfter(false);
mFromImage.startAnimation(mFadeOutAnimation);

Upon completion of this animation, the method onAnimationEnd(..) is called, which will load the next image. Alternatively, one can also use an AnimationListener to detect the end of an animation.

After the loading the next image, repeat the animation but reverse the alpha values in AlphaAnimation to fade in the next image.

Please see the full source code here.

To try out the difference between Hardware Accelerated Animations and traditional software rendered Animations, simply change the "android:HardwareAccelerated" property in the application Manifest.

Asynchronous downloading of bitmaps using ExecutorService

A naive way to download bitmaps is to just make a HTTP connection in the getView and set the bitmap using mImageView.setImageBitmap(). This would cause severe lag and would potentially cause an Application Not Responding (ANR) dialog to appear, because the UI thread would have to wait until the image is downloaded. This simple way of image download is sometimes done as an initial implementation, but then forgotten in the final version. Android has a mechanism to help find those accidental network (or filesystem) accesses, and we recommend to enable "Strict Mode" during development time. This will allow to log any time an application accesses the network from the UI thread.

The recommended way to download any bitmaps is in a separate thread. This can be done either using the Android AsyncTask or the Java concurrency framework Executor classes. In addition to downloading the bitmaps concurrently, a further speedup can be achieved by caching the bitmaps locally to avoid any future network access altogether.

The following snippet creates a fixed size thread pool ( newFixedThreadPool) with 5 items which means that there will be up to five images that are downloaded at the same time. All the other download requests are stored in an unbounded queue.

ExecutorService  mExecutorService = Executors.newFixedThreadPool(5);

See the full source code here.

Caching the images for faster launching

In our example, a user may have a large number of photos in a Picasa album. In order to avoid having to download all the images again each time a user enters into a particular album, the application will cache downloaded photos in local storage. This improves the perceived performance of the app significantly.

Google TV devices can have removable (USB-Drive) filesystems which are not always available. In our code sample we check first if any external drive is available, if not, we use the app's default Cache directory, which is smaller and may be wiped if the system needs to free up memory.

if (android.os.Environment.getExternalStorageState().equals(
        android.os.Environment.MEDIA_MOUNTED)) {
    mCacheDir = new File(android.os.Environment.getExternalStorageDirectory(), "List");
} else {
    mCacheDir = context.getCacheDir();
}
if (!mCacheDir.exists())
    mCacheDir.mkdirs();

Another pitfall with caching is that sometimes an application will pre-load many images which the user never actually scrolls down to see.

If you have a lot of images in your GridView/ListView, you may end up downloading a large number of images that your user never scrolls down to see. The best solution to this issue is to lazy load the images on demand in a separate thread, and then placing them into the ImageViews within the main UI thread.

An example for this can be seen in the source code ImageManager class.

Known Problems

Keep in mind, Android Hardware acceleration for 2D drawing operations is a new technology which ties deeply into the graphics drivers of the devices. There may be different behaviour between Mobile Devices and Google TV devices, and as hardware differs across devices, some of the devices may exhibit subtle bugs.

If you chose to hardware accelerate your applications, make sure to extensively test your app on different device hardware and watch out for subtle UI rendering bugs. For example in some instances extremely large fonts (60+ dps) will sometimes cause the text rendering engine to run out of memory and cause characters to not be rendered correctly, or not rendered at all.

So, while hardware acceleration clearly increases your app performance, make sure to test for any negative side effects before releasing your app to the Google Play Store.

Summary

In this example application we demonstrate several key techniques to speed up your Google TV application. We show how to use hardware accelerated Transitions between Views in a slideshow, how to speed up the download of images, and how to cache images on the local filesystem to improve overall application performance.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.