Thursday, October 17, 2013

ADF Mobile: Listening for changes to preferences

Lately I've been doing quite a bit of prototyping and, as is the case with such activities, I kept coming up with weird requirements that didn't have any apparent answers available .... some can be solved with a bit of ingenuity, the others leave me a few hair strands less.

Oracle ADF Mobile is a pretty neat framework for designing cross platform mobile apps. I was tasked with creating a prototype that communicates with a REST service to fetch some data.

As I went about with the exercise, I decided that I wanted to store the server configuration and user credentials in the application preferences.


Done. Next I wanted to refresh my controllers every time the preferences changed ... well this is where I got stumped! There is no preference-change-listener that I could implement.

Fortunately, there is an alternative - a feature level LifeCycleListener - which has only two methods activate() & deactivate() which are invoked when the feature is displayed and hidden. Every time you access the app's settings page (on your android phone) you are forcing the "Feature" to "deactivate" and then "activate" when you come back.

It is in this listener that you could employ a nifty hack to check if your preferences have changed or not. I chose to verify the hash codes to determine if the preferences had changed; and accordingly invalidate the required content.

So I ended with the following code for my listener:


public class PortalFeatureListener
  implements LifeCycleListener
{
  private long prefsHashCode = -1;

  public void activate()
  {
    // Verify if the hashcode of the preferences has changed or not.
    String prefs = "" +
     AdfmfJavaUtilities.evaluateELExpression(
        "#{preferenceScope.application.serverConfig.connUrl}") +
     AdfmfJavaUtilities.evaluateELExpression(
        "#{preferenceScope.application.userCredentials.username}") +
     AdfmfJavaUtilities.evaluateELExpression(
        "#{preferenceScope.application.userCredentials.password}");
    
    if(prefs.hashCode() != prefsHashCode) 
    {
      prefsHashCode = prefs.hashCode();
      refreshControllers();
    }
  }

  public void deactivate()
  {
    // Do nothing for now.
  }
  
  private void refreshControllers() 
  {
    // Do something here.
  }
}


, which gets configured in the adfmf-feature.xml file.



Hope this was useful to you.


No comments: