Wednesday, January 27, 2010

Android App Optimization: Using Reflection to test if an Android device is using 'Live Wallpapers'

I agree this may be a a pretty rare usecase, but I've just spent an hour figuring the details out so I thought it only polite to share them. Oneday, someone, somewhere may benefit.

What is Reflection?
It's been around almost as long as Java, described here and examples from Sun here

Why bother?
We've been receiving complaints that our Buzz Widgets are lagging on the Google Nexus One when Live Wallpapers are enabled. A little testing showed that this was down to the apps blurring out the desktop and rendering the content on top of it. If the desktop has a Live Wallpaper running on it, then blurring it eats some serious processor cycles. I understand that Reflection is more costly than directly calling the APIs, but this is just one simple call.

Why use reflection, not the actual API?
I'd much prefer to only have one version of each of our apps in the Android Market and the APIs for this only became available in the 2.1 SDK. Reflection enables us to use the APIs where available, whilst still letting the app run on devices with older firmwares.

How?
Well to get to the point we want to perform the test

if(WallpaperManager.getInstance(this).getWallpaperInfo() != null){//Live Paper, don't blur}

To do this with Reflection we have to use the methods Class.forName(""), Class.getDeclaredMethod() and Object.invoke() a little like this:


boolean blurBackground = true;
//get the WallpaperManager Class
Class classWallpaperManager = Class.forName("android.app.WallpaperManager");
if(classWallpaperManager != null)
{
//find its .getInstance(this) method
Method methodGetInstance = classWallpaperManager.getDeclaredMethod("getInstance", Context.class);
//invoke the WallpaperManager's .getInstance(this) method to get one
Object objWallpaperManager = methodGetInstance.invoke(classWallpaperManager, this);

//discover the WallpaperManager Object's .getWallpaperInfo() Method
Method methodGetWallpaperInfo = objWallpaperManager.getClass().getMethod("getWallpaperInfo", null);
//invoke it
Object objWallPaperInfo = methodGetWallpaperInfo.invoke(objWallpaperManager, null);
if(objWallPaperInfo!=null)
{
Log.d("WidgetDroid","WallpaperInfo not null");
blurBackground=false;
}
}

Also to ensure it is only run on Android 2.1+ devices I also wrap it in a quick Android Version check and a try/catch block for future safety:
if(Double.parseDouble(android.os.Build.VERSION.RELEASE)>=2.1){...}

Job done, now if the device is using a Live Wallpaper the apps background isn't blurred and all is well again in our Widget World.

10 comments:

Anonymous said...

[url=http://www.ile-maurice.com/forum/members/wetter-vorhersage.html][b]deutsch wetter[/b][/url]

[url=http://www.ile-maurice.com/forum/members/wetter-vorhersage.html][b]wetter online[b][/url]

オテモヤン said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...

http://chaosgone.blogspot.com/2008/08/germanys-current-top-20-popular-songs.html

Anonymous said...

http://www.facebook.com/pages/weathercom/298713874092 www.weather.com

Anonymous said...

http://www.facebook.com/pages/weathercom/298713874092
www.weather.com

Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...

After reading you site, Your site is very useful for me .I bookmarked your site!