Skip to content Skip to sidebar Skip to footer

Android, Best Way To Provide App Specific Constants In A Library Project?

I am creating a library project for a number of android apps. The apps all have some common functionality that I wish to include in the library project but the library project func

Solution 1:

Option #1 Extend your AppConstants class in each project

Better Option#2 Use XML resources to define the constants

<?xml version="1.0" encoding="utf-8"?><resources><itemtype="integer"name="app_id"format="integer">6</item></resources>

then you can retrieve them by

Context.getResources().getInteger(R.integer.app_id);

add the xml file to your resources in each project with only the values you need different

Solution 2:

I don't know of a great schema to do that but it would certainly work this way:

define some base class in your library

// class, enum or whatever you want it to be. classBaseConstants {
    // use some real singleton insteadpublicstaticfinalBaseConstantsinstance=newBaseConstants();

    // define those values - sadly static inheritance does not workprivatestaticfinalintAPP_ID=0;
    privatestaticfinalintCURRENT_APP_ID_KEY=24;

    // so we have to do that via methodsprotectedintgetAppId() {
        return APP_ID;
    }
    protectedintgetAppIdKey() {
        return CURRENT_APP_ID_KEY;
    }
}

let each Activity that wants something custom implement that

classApp1ConstantsextendsBaseConstants {
    publicstaticfinalApp1Constantsinstance=newApp1Constants();

    privatefinalstaticintAPP_ID=1;

    // want a different APP_ID here.protectedintgetAppId() {
        return APP_ID;
    }

    // getAppIdKey not implemented here, uses default
}

Use that class as context to the constants for your library

classLibrary {
    publicstaticlonggetCurrentAppId(Context context, BaseConstants settings){
        returngetLongPreference(context, settings.getAppIdKey(), settings.getAppId());
    }
}

Activities would be like so

classmyActivityextendsActivity {
    // each Activity can implement it's own constants class and overwrite only some valuesprivatestaticfinalBaseConstantsCONSTANTS= App1Constants.instance;

    privatevoidwhatever() {
        longappId= Library.getCurrentAppId(this, CONSTANTS);
    }
}

classmyActivity2extendsActivity {
    // or could just use the default onesprivatestaticfinalBaseConstantsCONSTANTS= BaseConstants.instance;

    privatevoidwhatever() {
        longappId= Library.getCurrentAppId(this, CONSTANTS);
    }
}

That schema is kind of ugly but it would work at least

Solution 3:

Define them as enum's in your library project, like

publicenumPlanet { MERCURY, VENUS, MARS }

Android proper takes another approach, the dreaded constant interface, like,

interfacePlanets {
  staticfinalintMERCURY=1;
  staticfinalintVENUS=2;
  ...
}

However, this is a well-known Java anti-pattern (constant interface, and is covered in detail in Effective Java, I quote,

The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class’s exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.

If you need the constants to have int values for some reason, and calling toString() on the enum isn't sufficient, you can give the enum's a extra information like,

publicenum ZipCode {
  LYNNWOOD(98036), SAN_JOSE(95112), ...;

  privateint zipCode;

  privateZipCode(int zipCode) { this.zipCode = zipCode; }

  publicintgetZipCode() { return zipCode; }
}

Note that enum's are slightly less performing than integer constants, but from a code organization and clarity perspective they are far superior.

Post a Comment for "Android, Best Way To Provide App Specific Constants In A Library Project?"