I'm using enums for units of different physical quantities, like meter
and miles
for the DISTANCE
. To use them in a generic way there is an interface Unit
which has the method convert(double)
.
To load the preferred units, a singleton is used:
public class UnitPreferences {
private static UnitPreferences sInstance;
private HashMap<PhysicalQuantity, Unit> mUnits;
/**
* Returns the instance of the preferred units collection.
*
* @param context the context
* @return Instance of the preferred units collection.
*/
public static UnitPreferences from(Context context) {
if (sInstance == null) {
sInstance = new UnitPreferences(context);
}
return sInstance;
}
/**
* Creates a new set of preferred units by fetching them from the Shared Preferences.
*
* @param context the resources
*/
private UnitPreferences(Context context) {
// Load the preferred units from SharedPreferences and put them in the mUnits HashMap
}
/**
* Returns all units of a specific physical quantity.
*
* @param physicalQuantity the physical quantity
* @return All units available to this physical quantity.
*/
private Unit[] getAllUnits(PhysicalQuantity physicalQuantity) {
switch (physicalQuantity) {
case DISTANCE:
return DistanceUnit.values();
// others...
default:
throw new RuntimeException("No units defined for " + physicalQuantity);
}
}
/**
* Returns the preferred unit of a physical quantity.
*
* @param phQuantity the physical quantity
* @return The preferred unit.
*/
public Unit getPreferredUnit(PhysicalQuantity phQuantity) {
return mUnits.get(phQuantity);
}
}
The PhysicalQuantity
enum:
public enum PhysicalQuantity {
DISTANCE,
// others...
}
The Unit
interface:
public interface Unit {
double convert(double value);
}
The DistanceUnit
implementing the Unit
interface:
public enum DistanceUnit implements Unit {
KILOMETER(R.string.unit_km, "km"),
MILES(R.string.unit_mi, "mi");
public static final double KM_PER_MI = 1.609344d;
private int label;
private String id;
DistanceUnit(int label, String id) {
this.label = label;
this.id = id;
}
@Override
public double convert(double meters) {
double km = meters / 1000d;
if (this == MILES) return km / KM_PER_MI;
return km;
}
}
The Problem:
The exception is thrown the first time I'm using the units:
Unit distanceUnit = UnitPreferences.from(context).getPreferredUnit(DISTANCE);
When I implemented it everything worked fine, now after it was merged into the master I'm getting a VerifyError
java.lang.VerifyError: Verifier rejected class com.example.app.UnitPreferences: com.example.app.Unit[]
com.example.app.UnitPreferences.getAllUnits(com.example.app.PhysicalQuantity) failed to verify:
com.example.app.units.Unit[] com.example.app.UnitPreferences.getAllUnits(com.example.app.PhysicalQuantity):
[0x28] returning 'Reference: java.lang.Enum[]', but expected from declaration 'Reference: com.example.app.Unit[]'
(declaration of 'com.example.app.UnitPreferences' in /data/app/com.example.app-2/base.apk:classes32.dex)
I've already cleaned and rebuild several times and turned off Instant Run. Can anyone give me a hint how to fix this error?