Flurry Remote Config For Android

Modes of Operation

When using Flurry Config, there are two modes of operation. In the first mode, referred to as the Simple Mode, the developer needs only to make a minimal number of calls and she will have the full config system at her disposal. The caveat, though, is that any new configs will only be loaded on the next app cold start.

The Advanced Mode gives the developer much finer grain control, allowing for greedy activation of a newly fetched config based on registering to listeners which notify of fetch. Choosing between the simple mode and and the advanced mode with its greedy activation is a choice to be considered. While the standard mode of fetch and activation on the next cold start allows for the utmost consistency in the UI, a greedy activation of a newly fetched config makes the app more responsive to the developers wishes. Example of when greedy activation may make sense: notify users that service is down or prompt user to update to latest version.

Getting Config Data

All config values are stored as strings but for convenience six getters are provided to allow the developer to interact with the config values in an easier manner.

public String getString(String key, String defaultValue);

public boolean getBoolean(String key, boolean defaultValue);

public int getInt(String key, int defaultValue);

public long getLong(String key, long defaultValue);

public double getDouble(String key, double defaultValue);

public float getFloat(String key, float defaultValue);

Upon calling a method other than getString the SDK will attempt to make some kind of meaningful conversion. In the case of getBoolean, it applies the same parsing scheme as Java Boolean.parseBoolean(String).

Why Defaults?

With each getter call there is a default value that must be passed in. In some circumstances it is possible that a config will not be available. Providing a default allows the config system to have a hard-coded fallback. It is also useful for testing.

Simple Mode

There are only two calls necessary in simple mode:

public FlurryConfig getInstance()

public void fetchConfig()

It is not strictly necessary but is a best practice to call FlurryConfig.getInstance() in Application.onCreate. This method acts as an initiator for the config system and will also cause the loading of any previously fetched configs on a cold start.

The simplest form of activation which would also fetch configs for the next cold start would look like this:

@Override public void onCreate() {

super.onCreate();

// Init Flurry new FlurryAgent.Builder().build(this, FLURRY_APIKEY);

// Setup Flurry Config and initiate fetch

FlurryConfig flurryConfig = FlurryConfig.getInstance();

flurryConfig.fetchConfig();

}

From here the developer can make getter calls as normal. This will ensure that the latest config will be fetched and loaded for the next cold start. In the meantime, the previously loaded config can be relied on.

Advanced Mode

It might be the case that a greedier application of the config is desired or necessary. Flurry Remote Config provides the tools necessary for this use case.

The Listener and Activation

In the simple mode a config is “activated” on the next cold start after the config is fetched. However, there is a method that allows the developer to directly activate a config (preferably once it’s been fetched).

public boolean activateConfig()

This will take a newly fetched config and apply it greedily.

However, there is very little point in calling activate if a new config has not been fetched. Hence, the SDK provides a protocol to which the developer can register a listener. The listener will be called back when a config has been fetched. The developer can implement the following methods in the listener interface:

public interface FlurryConfigListener
void onFetchSuccess();
void onFetchNoChange();
void onFetchError(boolean isRetrying);
void onActivateComplete(boolean isCache);

To register your listener, a handler can be provided optionally.

public void registerListener(FlurryConfigListener configListener) public void registerListener(FlurryConfigListener configListener, Handler handler)

The user specified handler, while perhaps seemingly an odd addition, is important. Flurry Config operates in a completely thread safe manner. When a listener is called all execution will take place on the handler provided. This has the effect of making sure that the developer controls the thread safety of any UI or app modifications.

Any Activity may register a listener. As a result, the app can update only the views which need updating and defer other views for later (on the cold start). A great example of this would be to register a listener in Activity.onCreate and have it update the UI on activate completion:

mFlurryConfig = FlurryConfig.getInstance();

mFlurryConfigListener = new FlurryConfigListener() {

    @Override public void onFetchSuccess() {

    mFlurryConfig.activateConfig();

    }

    @Override public void onFetchNoChange() {

    // Use the Config cached data if available

    }

    @Override public void onFetchError(boolean isRetrying) {

    // Use the Config cached data if available

    }

    @Override public void onActivateComplete(boolean isCache) {

    // Get the Config data

    getConfigData();

    }

};

mFlurryConfig.registerListener(mFlurryConfigListener);

mFlurryConfig.fetchConfig();

In order to ensure that the application does not get caught in a transitional state by some unanticipated caller on a successful activation all listeners will be notified of the activation. A listener may then update its state with the latest config if that is desired, much in the way that a listener can update itself on activate completion.