Reusable Aspect Library for Android, Part 1

There are various projects / tutorials / blogs out there about how to integrate AspectJ into the Android development process. They generally show you how to setup an application project to use AspectJ, with the aspects in the project itself.

However the way I tend to use AspectJ in Java projects is to try to put them into reusable libraries so that they can be applied to multiple projects. After all they are supposed to be used for cross-cutting concerns which are common to many applications. Searching the internet, I did not manage to find much information about how to do this in Android.

So here are some examples of one solution I found when using Eclipse (Windows version). If  you are not already familiar with creating and setting up Android projects in the Eclipse IDE, and with using AspectJ, have a look at the documentation for Android and AspectJ.

These are the requirements for the samples:

Note that the Android tools tend to be a bit brittle, so different versions may have changes (and bugs). So the examples may not work if you are using a different version.

Also I had the following design goals in mind:

  • keep it as simple as possible
  • stick to using Android libraries

With Eclipse you can put code in separate Java projects and either reference them from an Android application either as a project or a jar, e.g. create a ‘glue’ Android library that references a Java library.
While this might work in Eclipse, it would make things much more complicated if I wanted to use another build system (e.g. Ant) to build the application.

Scenario 1: Self-Contained Aspect Library

In the first example, we will create an android library that contains all the aspect code, and use it to apply the aspects to some code in an application.

Here are some instructions on setting up an Android library with aspects, along with some sample code.

The Test Application

This is just a very simple app to demonstrate the aspects working.

1. Create a new Android application project and add some code that the aspects can intercept.

public class MainActivity extends Activity {

private Button testButton;

 protected void onCreate(Bundle savedInstanceState) {

 testButton = (Button)findViewById(;

private OnClickListener testButtonListener = new OnClickListener() {
 public void onClick(View v)
 // invoke the method to be traced

 public void testMethod()
 Toast.makeText(this, "Inside test method", Toast.LENGTH_SHORT).show();

2. Add the AspectJ nature to the application project.

If you already know how to setup AspectJ in an Eclipse project, then you can skip the next bit …

To add the AspectJ nature to the application project, there are 2 ways of doing this:

a. Using the AJDT plugin
Right click on the project in the Package Explorer to bring up the context menu.

  • Click ‘Configure’
  • Click ‘Convert to AspectJ project’

Menu to convert to AspectJ project

b. Do it manually

  • Edit the ‘.projects’ file for the project.

Replace the java builder …


with the AspectJ builder …


and then add the AspectJ nature …


The edited file should look something like this:

<?xml version="1.0" encoding="UTF-8"?>
  • Add the AspectJ runtime jar to the classpath for the project.

The jar is named ‘aspectjrt.jar’ and it is probably a good idea to use the one that came with the AJDT plugin, which should be located under your Eclipse install at ‘plugin/org.aspectj.runtime_x.x.x’.

There are various ways of doing this, but if you have AJDT installed, the easiest way would be to add it as a library in your ‘Java Build Path’ dialog. In the ‘Java Build Path’ dialog, select the ‘Libraries’ tab, and then click the ‘Add Variable’ button. Then in the ‘New Variable Classpath Enty’ dialog that comes up, select the ‘ASPECTRT_LIB’ entry and click the ‘OK’ button.

Add aspectrt.jar as variable

To make the sample code a bit more portable, rather than doing it this way,  I’ve just copied ‘aspectjrt.jar’ to a directory named ‘lib’ in the project and added it to the classpath from there.

The Aspect library

This is the Android library project that will contain the aspects.

1. Create an Android library project

2. Add the AspectJ nature to the library project (the same as for the application project)

3. For these samples I am going to show a very common usage of AOP – tracing. So add some an AspectJ tracing code to an aspect file in the library project, with the pointcut configured to intercept some code in the application project.

public aspect TraceAspect {

    private final static String TAG = "Aspect-Trace";

    // pointcut to intercept a method in the application project
    protected pointcut traceOperations(): execution(***.testMethod(..));

    before() : traceOperations() {
        Signature sig = thisJoinPointStaticPart.getSignature();
        log("Entering [" + sig.toShortString() + "]");

    protected void log(String msg)
	Log.i(TAG, msg);

4. Add the aspect library project as an Android library for the application project.

Add aspect library project to application

5. Also add the aspect library project to the AspectPath for the application. Do this in the ‘AspectJ Build’ dialog for the application project.

For the application project, right click the project in the Package Explorer to bring up the context menu.

Then either …

  • Click ‘Build Path -> Configure Build Path …’ to bring up the project properties dialog
  • Click ‘AspectJ Build’ in the side menu

or …

  • Click ‘AspectJ Tools -> Configure AspectJ Build Path …’

In the ‘AspectJ Build’ dialog, click the ‘Aspect Path’ tab. Then click the ‘Add Project…’ button and select the aspect library project.

Add aspect library to aspectpath of application

Run the application

Now run the application in your device or emulator, making sure that the code that you want to trace is invoked.

Sample app 1

For the sample app, just click the button ‘Click to test tracing’, and then check in LogCat that the aspect tracing has occurred.

LogCat tracing 1

The Sample Code

You can download the sample code for this example, from GitHub.

Running the sample code:

  • Unzip the zip file containing the Eclipse projects.
  • Import the projects into your Eclipse IDE.
  • The sample projects have Android 4.0 (API level 14) as the Android build target. So you need to either have API 14 present in your Android SDK installation or change the build target for all the projects to another API version.
  • Optionally you may have to adjust any application or class paths to suit your development setup.
  • Build and run the sample application project.
  • Check LogCat to see if the aspect tracing is present.


The problem with this example is that the aspect library isn’t really all that reusable.

If you wanted to use the library in another application, chances are you would have to changed the pointcuts to match the code you want to intercept in the new application.

In the next part of this blog, we will make some improvements to it to make it more reusable.

Path Problems: Java (Android), Windows 64 and 2 Drives

I recently updated my installation of the Android SDK and ran into a problem that I’ve alway had on my current computer – the SDK Manager would not run after the update.

This is due to a Java path problem for a particular setup:

  • a computer running 64-bit Windows (Windows 7 in my case)
  • a computer with more than one disk drive installed

I also have Java 6 64-bit installed on the computer (not Java 7 as I use it for Android development).

Android SDK Manager – it no work

To re-iterate the issue: after installing or updating the Android SDK on a system with this setup, the SDK Manager may not be able run.

When trying to start the SDK Manager, in the ‘tools’ directory of the SDK installation, the batch file ‘android.bat’ is run. Inside the batch file it sets various path variables that point to libraries or to your Java installation that is required to run the SDK Manager.

This is where I run into problems.

One issue is this line in ‘android.bat’:

for /f %%a in ('%java_exe% -jar lib\archquery.jar') do set swt_path=lib\%%a

Here it is looking for the file ‘swt.jar’ which is located in the SDK installation under ‘tools\lib\x86’ or ‘tools\lib\x86_64’ depending on whether you are running a 64-bit system.

If you have only 1 drive in your system, then this should work. But if, like me, you have two drives then it may not work and the variable swt_path is not set.

Then there is this line where it tries to find Java:

call lib\find_java.bat

This runs the batch file ‘find_java.bat’ to set the variable ‘java_exe’ to point to the path of java.exe in your Java installation.

for /f %%a in ('%~dps0\find_java.exe -s') do set java_exe=%%a

Once again in my system this doesn’t work and the batch file can’t find my Java executables.

By the way when you try to do a build with Ant, it runs ‘platform-tools\dx.bat’ which also calls ‘find_java.bat’, so it runs into the same problem of not finding Java.

Why Does This Happen?

It seems this all has to do with the way Windows x64 handles the long and short format of file (and directory) names when working out paths.

Of course, this is for my particular setup. On your system it may all work fine – but you only have to do a quick google to see that many others have similar problems.

If you have this issue, then it’s worth checking for more common errors first, e.g.

  • the appropriate version of Java is installed correctly
  • JAVA_HOME and PATH environmental variables have been configured

Other Java Programs – GMote

I was recently reminded of all this when I was setting up my HTPC. This is a Windows 7 64-bit PC, once again with 2 drives (one for applications and the other for storing media files).

I was trying out GMote (an Android remote control app for playing media on a computer). This has a server component which runs on the computer and is a Java program.

After doing the default installation, I tried to run the GMote server and kept getting an error “Unable to load library ‘libvlc'”. After checking that the ‘libvlc’ library was in a folder in the PATH environmental variable, this error still kept occurring.
It took me a little while to find the problem with getting the GMote server to run:

  • I had the 64 bit version of Java installed, so I installed the 32 bit Java and pointed the JAVA_HOME environmental variable to it.
  • Since the path to the support library was under the default installation of GMote server at “C:\Program Files (x86)\…”, I re-installed the GMote server to another directory name that did not contain any spaces “C:\media\…”.

Finally it worked.

Why Two Drives?

At this point you might ask why do I have 2 drives on my computers?

I tend to install the system and application files on one drive, and data files on the other, I find this convenient for various reasons:
Backup – I can use different backup strategies on the different drives, e.g. do an disc image backup on the system and application drive and some other type of backup on the data that I want on the other drive. I also point the TEMP environmental variable to the data drive so that the temporary files don’t clog up my image backups.
Performance – Use a SSD for the operating system and applications disk for faster booting and app loading (Of course it would be nice to have a SSD for the data drive as well, but if you have a lot of data then this would be very expensive!).

The Moral of the Story …

So in this particular setup of trying to run Java programs on 64-bit Windows on a computer with multiple disk drives, I follow these guidelines:

  • check which version of Java is required by your program (64-bit or 32-bit)
  • check whether it requires the JDK or JRE
  • install Java programs in a path that doesn’t have spaces in the directory names, as you might do on a UNIX or LINUX system
  • point your JAVA_HOME environment to the appropriate Java installation (you can do this in a batch file before launching the Java program so that it is only local and doesn’t affect other Java apps)

So how did I resolve Android SDK issue on my system? If you google this issue, there are various suggestions as to how to fix it. These include things like digging into the Windows and Java internals, registry hacks, etc.

For me, I just took the easy route of editing android.bat to point the variables to the correct paths on my particular system. I know this is not the best way to deal with it, but after many frustrating hours of research, configuration and testing, I wanted to get things up and running quickly.
It’s a shame you have to waste so much time digging into Android issues to find the causes (and if you’re lucky, the solutions) of these problems. It’s not like running Windows x64 or having multiple drives on a computer is all that unusual.

But then the Android build tools have always been a bit flaky, so I guess it’s part of being an Android developer.

Android Fragmentation – A Developer’s Perspective

Much has been written about Android fragmentation, and how it affects consumers. But what does it mean for Android developers?

Well, more testing – lots more testing. And, of course, all the associated support and bug fixing issues for dealing with multiple versions.

You have to test for:

  • All the Android versions that you want to support for your app.
  • Then there is testing for different screen sizes (both in portrait and landscape mode, of course, and handling orientation changes between them).
  • Also testing for manufacturer phones that have a custom UI, especially if your app interacts with the UI in some way – for instance for widgets or if the app accesses system settings screens.

This sounds like a lot of work, and it is, if you are diligent about testing and providing a good experience for your users.

But then is this much different for developers writing web applications that work in browsers?

In that case you would have to test your app for:

  • All the major browsers that you want to support (Firefox, Internet Explorer, Chrome, Opera, etc).
  • Different versions of these browsers that might still be in use (and how to degrade gracefully for older versions).
  • Once again different screen sizes, particularly if you are supporting mobile devices as well as desktop.
  • Exception testing in cases where the user has disabled Javascript or is not using cookies.

So, from a developer’s perspective it’s not all that different from the issues that Android developers have in terms of having to do a lot of testing and app support.
They just don’t call it fragmentation, because it isn’t. But the issues with having to support multiple client environment versions are the same.

I consider that this is the price that has to be paid for working on systems that have some degree of ‘openness’ (in contract to systems that are tightly controlled by the company that owns it).

If you support openness in software, then I think this is a price worth paying.

Update 7/3/2015

Recently I have been investigating web (Javascript) frameworks to use for an upcoming project.

Then I came across this post about how bad fragmentation was in that area. Basically the gist of the article was that there were so many frameworks and libraries for building web applications, and the landscape was constantly changing. The author used the phrase ‘crisis of churn rate‘ to describe the mess.

Even frameworks like angularjs, which seems to have a lot of mind share at the moment, will have a new version (2.0) coming out possibly at the end of the year which will not be backwards compatible with the current version. More fragmentation!

After having read that post, and done a bit of research myself, it just reinforced my view that Android fragmentation was not really so bad after all.

Now, which Javascript framework/library/tool/combination should I be using …

Advanced Testing Tips for Android, Part 2

In part 1 of this article, I discussed some of the merits of Android testing on the emulator and rooted devices. In this concluding part, I’ll have a look at the software side of things.


It is often useful to include tracing code while developing, one common usage is to trace the entry and exit of methods calls for example.

However it is generally recommended to remove tracing (and debug) logging from releases. This can be a hassle if these trace log statements sprinkled in your code. If you are using proguard to obfuscate your release version, then that is one option you can use to disable the tracing.

Another way is to use an AOP library like AspectJ to handle tracing instead (there are various examples of how to do this in Android available on the internet, just google it).

Some advantages of using AspectJ to handle tracing are:

  • The AspectJ tracing code could be put in separate library project, which may only be included in development builds (i.e. leave out the library in the build script for the release build).
  • Use of pointcuts is more configurable, as it can be used to trace as much or as little of your code as you require. This is useful to target the tracing to areas of your code when checking for errors.

Generally I would leave general method tracing disabled, but it is sometimes useful when running automated tests, e.g. when doing Continuous Integration or running Monkey, to trace the method flow in case there are crashes or other problems.


This is another useful testing tool, but sometimes there are sections of your code that you don’t want to be run while testing with Monkey.

In this case, you can disable functionality for those sections of code when testing with monkey using ActivityManager.isUserAMonkey().

if (!ActivityManager.isUserAMonkey())
    // only run if not running in Monkey

In my case I used this because the app I was working on had some functionality to run other apps on the device. If this code was run during Monkey testing, then Monkey would continue to run on the secondary app rather than the main app that I wanted to test.

Another example of it’s usage is in the Android API demos (to stop Monkey running any ‘dangerous’ code) :

Accessory Apps for Testing

To assist in testing, it may be useful to write some additional apps to handle various accessory tasks:

  • configuration of the device before running tests
  • loading test data, for instance I wrote a simple app to load test contacts and SMS messages.
  • test for failures in intents passing, e.g. if the main app runs other apps using intents, you could use intents to run an app that deliberately fails to see how the main app handles it

Android App – Address Location Finder

I’ve just released an Android app on the market, it is a location utility app called Address Location Finder.

Address Location Finder
Address Location Finder

Basically it allows you to locate an address – then pass that location onto other apps or mapping utility websites.

You can just enter the address to search for, or get it from your contact list or get it from a SMS (if the message contains only the address).

The app then uses the Google geocoding services to find the location for that address. Once it has the location then you can do various things with it:

  • view the location with the simple built-in map, for simple navigation
  • pass the location to other mobile apps, such as StreetView, Google Maps, etc
  • pass the location to some useful mapping utility websites, these include sites that:
  • showing a radius around address location
  • find another location with a particular distance and bearing from the address location

Use address location

This is the free version, and while this first release is a BETA all the basic functionality should work.

If you have a chance to try it, please let me know what you think about it or if you come across any problems with the app.

Available in Android Market

Advanced Testing Tips for Android, Part 1

I’m currently developing an Android app and have been reading up on Android testing. Here are some tips that I’ve come across and found useful, as well as some ideas of my own.

Emulator vs Device

Testing on a real device is generally recommended over using the Android emulator for various reasons:

  • You should test as close as possible to the user environment.
  • A device is a more realistic environment for acceptance testing.
  • The emulator is slow, and often buggy. I’ve encountered issues with various versions of the emulator, when trying to test things like orientation changes, location services, etc.

While I agree that you should do most of your testing on real devices, sometimes testing on the emulator can be a useful addition.

Advantages of Testing on the Emulator

1. You can increase memory and heap for an AVD (Android Virtual Device).

This may be necessary if you have a lot of tests to run together or have complicated tests (e.g. if using recursion). Of course devices are limited to how much memory they have installed and could run out of memory when running test suites.

2. For testing with particular configurations, e.g system settings such as GPS.

You can setup an AVD with GPS on and another exactly the same except with GPS off (once configured, they would be saved as snapshots). Then you could have annotations in the test cases for which tests to run in which environment.

If you were testing this with a device, then you would need to remember to configure the settings before the tests are run. This may be alright for manual testing, but a major hassle for automated testing (for instance, if you’re using Continuous Integration practices).

In fact, a tool like the Jenkins Android Emulator plugin could be configured to start the appropriate AVD in the emulator when required (or even create one based on a set of configurations).

3. The emulator is free.

Of course using the emulator is cheaper than buying a truckload of devices, especially with so many Android version and screen sizes out there. You can use the emulator to fill in the gaps for whichever configurations you don’t have devices for (is it worth buying separate devices to test Android version 2.3 vs 2.33, for instance).

Testing on a Rooted Device

Most advice about using rooted devices for testing seems to be, DON’T. Most of the time this is good advice, as you want your test environment to be as close to what your customers are using as much as possible.

However you might find it sometimes useful to run some of your tests on a rooted device. In particular, being able to have read and write access to otherwise secure directories can be useful.

Some examples of this would be:

  • to copy a test database onto the device
  • copying junit report files off the device for archiving
  • doing a full backup of various device configurations, to restore later for testing

Some more tips later in part 2 of this article.

Flash – don’t shoot the messenger

I have been reading that Adobe is stopping development of Flash for mobile devices (official announcement). If fact there have been many recent articles lately about the demise of Flash in general, they seem to argue that Flash is a ‘bad’ web technology and should be dumped in favour of HTML 5.

One of the reasons cited for Flash being bad was that it is used to create those annoying ads and banners. I think this is confusing the Flash technology itself with its usage – in other words blaming Flash when the real culprits are the purposes to which people have used it (or abused it).

As a former web developer, I remember that before Flash came along there were equally annoying popups and banners being produced using animated GIF’s. I suppose if Flash were to go away we would still be getting those annoyances using whichever is the current web animation technology of the day

Don’t get me wrong, I know that Flash technology does have real issues regarding stability, performance, etc – but then just about every web technology has its problems (including HTML when being used to create interactive web applications).

Luckily there are also other articles with a more balanced view, e.g. “Adobe Flash: Still the 800-Pound Gorilla”.

Using load-time AOP to help testing and debugging

After reading this blog ‘Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy‘, it reminded me how handy AOP tools like AspectJ are, in testing and debugging applications – particularly on servers.

How many times have you encountered a problem or bug in staging (or common test or reference) servers that you can’t reproduce in your own dev server? Ideally deployments should be consistent and reproducable so that this should never happen, but unfortunately in real projects that is not always the case.

Sometimes various issues can cause these differences:

  • manual configurations to the build process
  • continuous integration not used rigorously
  • different environmental settings on different server instances
  • different external services used in development, as opposed to a staging environment

Factors like these may lead to inconsistent builds or differing behaviour in different server environments.

I’ve found that using load-time weaving with AspectJ can be useful testing and debugging the application code on a staging server, without requiring any source code changes. The good thing is that because it doesn’t change the actual build artifacts on the file system (of course the code is changed when the affected classes are loaded!), you can remove the load-time weaving any time and revert back to the original code without having to do another build.

Here are some examples of what can be done to assist testing and debugging on a server that is not directly controlled by the developer. I’m assuming here that you are able to implement load-time weaving on the server.

Also if you are not familiar with AOP and AspectJ, else please read the AspectJ documentation or a book on AspectJ, such as the excellent AspectJ in Action.


The generic introductory example for demonstrating how useful AOP is, seems to be tracing. The ability to add logging code to trace (program flow, method parameters and return value, etc) is very handy for debugging, particularly when using pointcuts to narrow the scope of the tracing to the sections of code that are problematic.

Here is a simple example with some test classes:

public class Customer {
  private String name;
  private String phone;
  private String address;

  public String getName() {
    return name;
  public void setName(String name) { = name;
  public String getPhone() {
    return phone;
  public void setPhone(String phone) { = phone;
  public String getAddress() {
    return address;
  public void setAddress(String address) {
    this.address = address;

public class AccountService {

  public boolean addCustomer(Customer customer, String accountId, boolean isNewCustomer)
    // real code to add customer to an account would be added here

    return true;

For the tracing code, you can use the examples from the AspectJ programming guide or the book AspectJ in Action.

Then in a trace aspect class, use a pointcut to trace the code we’re interested in (in this case AccountService.addCustomer()).

pointcut traceOperations() : execution(* trace.blogexample.AccountService.addCustomer(..));

When the code is run, you might get some tracing, showing that the code was run and the parameters that were passed to the method in the pointcut.

Enter  [trace.blogexample.AccountService.addCustomer]
  [ This: trace.blogexample.AccountService@6262937c]
  [Args: (trace.blogexample.Customer@35c0e45a,ABC123,true)]
Exit  [trace.blogexample.AccountService.addCustomer]

Even more useful is if you combine the logging code with reflection to trace not only simple values, but also the contents of objects that you are interested in.
For the above example you might get tracing that shows the fields of objects passed to the method as parameters.
Hopefully the info from the tracing may be helpful in fixing a bug or problem.

Enter  [trace.blogexample.AccountService.addCustomer]
  [ This: trace.blogexample.AccountService@1d5a0305]
  [Args: (trace.blogexample.Customer@377653ae[
  name=John Smith
  address=1 Test Street
Exit  [trace.blogexample.AccountService.addCustomer]

As I’ve mentioned, you can target where the want the tracing to occur:

  • by setting the pointcut to trace in details the areas of code that are (or that you think are) causing problems,
  • where exceptions are being thrown (using an After throwing advice)

You can also build on the AOP tracing to do other useful things, for example I have an open source project (TestDataCaptureJ) that uses tracing to capture data to use in unit testing.

Data Validation

Instead of just tracing, you can go further by doing some data validation as well.

For instance you can insert some code to validate the parameters for a business method, and log any validation errors.

Another way is to use tools, such as Contract4J, to test compliance (checking for preconditions, postconditions and invariants in the business requirements). Use load-time weaving to hook in the Contract4J configuration for business methods that you want to test.

Method Replacement

Another technique I sometimes use is to replace methods invokations in the app with test code.
This involves creating an Around advice for a pointcut that includes a method we want to replace.
Then inside the Around advice you can:
1. run another method altogether

So instead of just invoking the original method …

Object returnValue = joinPoint.proceed(args);

invoke another method with the same return type.

Object returnValue = newMethod(args);

2. run with different parameters

Invoke the original method, but pass in different parameter values (of course the parameter types must match the method signature)

Object returnValue = joinPoint.proceed(newArgs);

So using method replacement techniques you can do things like:

  • inject your own data to test a particular scenario
  • proxy external calls, e.g. for a method that uses an external service, replace with a method that returns some test data we can use for diagnosis


These are just some ideas that I have found useful when testing and debugging issues in app development. They can be easily applied to your development environment, but using load-time weaving with AOP also makes them useful when you encounter problems in a server that is not directly under your control.

Of course these techniques do not replace your standard tools and debuggers, it is just another tool in your toolbox.

Using a custom ServiceLoader in Android

For those looking for a way to create modular and extendible code using some sort of ‘plugin’ architecture, one of the possibilities is to use the ServiceLoader class.

A service provider is a factory for creating all known implementations of a particular class or interface S. The known implementations are read from a configuration file in META-INF/services/.

Here are some examples of it’s usage in Java:
Creating Extensible Applications With the Java Platform

What I was after was use it in Android, and to be able to put the service implementation classes in their own libray project or jar file, so they could be used independently in a modular fashion. A possible use of this structure is to have different ‘plugins’ for different versions of an app.

There are other similar java plugin frameworks out there, but I thought I’d stick with something that already exists in Java rather than learning yet another API.

However there are some issues with using ServiceLoader in Android, mostly having to do with where to put the configuration file that contains the list of plugin implementation classes. Unfortunately ServiceLoader is hard-coded to look for the file at ‘META-INF/services/’, which makes it hard if we want to make it work in Android.

This article ‘Using serviceloader on android‘ gives some ideas about how use it with Ant. However I wanted a solution that could also be used with Eclipse.

Customizing ServiceLoader

Because ServiceLoader is a final class, it cannot be subclassed but we can still customize it by making our own copy from the Java SDK source code. For example, let’s get a copy of from JDK 1.6 source, and rename it to CustomServiceLoader.

Looking at the source, the first thing we notice is that the location for the config file is hard-coded:

private static final String PREFIX = "META-INF/services/";

Then here is where that location is used (it is only used when hasNext() is called on the iterator due to the lazy initialization pattern):

public boolean hasNext() {
  if (nextName != null) {
  return true;
  if (configs == null) {
    try {
      String fullName = PREFIX + service.getName();
      if (loader == null)
        configs = ClassLoader.getSystemResources(fullName);
        configs = loader.getResources(fullName);
    } catch (IOException x) {
      fail(service, "Error locating configuration files", x);
  } ...

There are several ways we could customize this class to make it easier to use with Android.

Option 1: Replace the hard-code PREFIX field with your own location

So in our custom class, we could just change the location for the PREFIX constant to point to somewhere else in our classpath. This is the quickest way, but suffers from the same inflexibility as the original ServiceLoader.

private static final String PREFIX = "";

Since the location is being looked up internally using getResources() or getSystemResources() from the classloader, all we have to do is to make sure the configuration file is in the classpath somewhere, and then tell CustomServiceLoader where to search for it.

Another idea for this option was to do it the ‘Android’ way and use the AssetManager to find the configuration file in the assets directory. This would mean passing the AssetManager as an extra parameter in the public API methods for CustomServiceLoader.
However the Android build process will only take into account the assets directory in the main project and ignore the assets directory in library projects, so the file would have to go in the main project. I prefer the configuration to exist in the library along with it’s code so that it could function as an independent unit, so I did not use the assets folder.

Option 2: Pass the location

Rather than hard-coding the location, we could just pass the location as an additional parameter when you want to load the services. This would mean changing the method signatures to pass the location parameter through (or store it) until it is needed. Hence instead of calling …


you would call …

CustomServiceLoader.load(MyService.class, "")

I did not end up using this option, since it would have required more substantial changes to the original class.

This is one of the caveats regarding copying source code and changing it, and why I generally dislike doing this. If you make any significant changes to it, then there is always the chance you will introduce bugs into the code (therefore requires more testing!). Also if the original code base changes, your code will not include those changes.

Making it Modular for Multiple Plugins

The above solutions would work if you only had one plugin (i.e. a jar or project containing some service implementation classes and a configuration file), but what if you wanted to be able to handle any number of plugins. My idea was to have each plugin as a independent unit, each with it’s own configuration file.
Then the app would load all the plugin classes it found and aggregate them to make all the service implementations available.

Why would you want to do this? Well, many Android apps have multiple versions, i.e. a paid vs a free version, or a lite vs a pro version. So you could have 1 plugin for the lite version offering a limited number of services.
Then for the pro/paid version, you could either replace the plugin with another version that offers more services or just add those extra services as addition plugins.

It would require a bit more work on CustomServiceLoader to allow it to handle this situation.

This means that, for instance, if the location you want is at ‘’, then if you have 2 plugin libraries or jars with their configuration files at that same location, then the apk will build since it would consider them to be duplicates:

Error generating final archive: Found duplicate file for APK:

Let’s have a look at the code again:

private static final String PREFIX = "";


public boolean hasNext() {
  if (nextName != null) {
  return true;
  if (configs == null) {
    try {
      String fullName = PREFIX + service.getName();
      if (loader == null)
        configs = ClassLoader.getSystemResources(fullName);
        configs = loader.getResources(fullName);
    } catch (IOException x) {
      fail(service, "Error locating configuration files", x);
  } ...

The problem is that the code is only looking at 1 location as specified by the PREFIX constant, but having the same location in multiple plugin libraries will break the build process due to duplicate file problem.
We can put the configuration files in different locations in each plugin library, but then how does CustomServiceLoader find them?

I’m still working on this, but got some ideas:
1. Add some code to be able to handle wildcards in the location.
Plugin1 would have the location of it’s configuration file at ‘com.yourdomain.services1/’.
Plugin2 would have the location at ‘com.yourdomain.services2/’.
We could pass is a wildcard location, such as ‘*’.

In the Spring Framework, there are classes such as ResourcePatternResolver and PathMatchingResourcePatternResolver that does something like this. This is what enables Spring to find ApplicationContext.xml in different locations. This seems to be the most flexible way of doing it, but requires more work.

2. Another way would be to use option 2 above (passing the location as a parameter), but instead of just 1 location, pass in multiple locations (in a Collection or array) and aggregate the results of the getResources() calls.
This is easier, but far from ideal, as you have to hard-code the locations of the configuration file in each plugin library somewhere.

Tips on handling orientation changes in Android 2

Here are some tips on how to handle and test orientation changes in Android 2

This post applies to Android 2.x, since onRetainNonConfigurationInstance() is deprecated in Android 3.x.

In my previous post I showed one method I use to test orientation changes. The standard way of handling orientation change is to save the results of expensive operations
in onRetainNonConfiguration(), and then when the activity is recreated that data can be re-used.

From the Android developer documentation

Finally, remember that onRetainNonConfigurationChange() should be used only to retain data that is expensive to load. Otherwise, keep it simple and let Android do everything.

And here.

This function is called purely as an optimization, and you must not rely on it being called

This means that onRetainNonConfigurationChange() is supposed to be an optimization, so the activity should be able to recreate the data if required

Now here is a list some things that I will usually save in onRetainNonConfigurationChange().

Expensive operation results – just like the documention says. After all you don’t want your app to be re-doing things like database queries, network calls or complex
calculations every time the user flips the phone.

AsyncTask – there are some situations where a running AsyncTask will be saved, so that it can continue it’s processing after the orientation change (rather than starting the task again). Makes sense since one of reasons to use an AsyncTask is to handle long-running operations.

Intermediate data – I was using some fields in the activity to hold some (non-expensive) data, so I didn’t bother to save it because I thought it was trivial. The result was NullPointerExceptions because that data was required either in the onCreate() or later on, e.g. onDialogCreate()when I wanted to display that data in a message. So you can either save this data, re-create it in onCreate() or at least do a null check before using it.

Maps – if the activity displays a map (e.g. using a MapActivity), then it might be more user friendly to save things like the zoom level, satellite view option, and the centre point of the map.  This is so that the user has a similar map view after the orientation changes.

Some other tips not related to saving state

Dialogs– if you are doing your own dialog handling, instead of letting the activity do it by using onCreateDialog() and showDialog(), then you need to handle the situation
where the dialog is displayed when the orientation change occurs. I generally let the activity do the hard lifting, except maybe in cases where the life cycle of the dialog doesn’t
match the activity, e.g. a progress dialog for an AsyncTask.
Generally in my unit tests, I will follow each dialog display with an orientation change to check that afterwards:
1. the dialog is still displayed
2. if the dialog shows data, that the data hasn’t changed

Layouts – if you have alternate layouts for portrait and landscape, goes without saying that you need to test both! This includes things like testing the order of focus for the views, etc. since the views may be in different positions in the different layouts.
This is the reason that in my previous post: Test Android orientation changes with Robotium I ran the test methods multiple time starting in both portrait and landscape mode.

Some more testing tips

  • Some versions of the emulator may have bugs that show up when your test invokes an orientation change, e.g. the 2.3 version will allow your app to change normally from portrait to landscape, but then it has problems when you try to change back to portrait again. The test will still run OK, the will not look right in the emulator window.
  • If you are using the emulator and have some Robotium or instrumentation test code to click on an item in a list by index, e.g. solo.clickInList(1). Then the orientation change may cause some test failures when going into landscape mode.
    This is because fewer items being displayed in the list in landscape than in portrait mode, of course this is only a problem is there are more items in the list than can be displayed in the view or ‘page’.
    See if you can use solo.clickOnText() instead with the option to allow scrolling if required.

If you can think of anything else that might be useful, please let me know!