我有一个写的类GenericComparator,根据方法名称在我的应用程序中根据方法名称进行排序 - 例如getPriority
import android.util.Log;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.Date;
public final class GenericComparator implements Comparator, Serializable {
private static final long serialVersionUID = -2293914106471884607L;
private static final int LESSER = -1;
private static final int EQUAL = 0;
private static final int GREATER = 1;
private static final String METHOD_GET_PREFIX = "get";
private static final String DATATYPE_STRING = "java.lang.String";
private static final String DATATYPE_DATE = "java.util.Date";
private static final String DATATYPE_INTEGER = "java.lang.Integer";
private static final String DATATYPE_LONG = "java.lang.Long";
private static final String DATATYPE_FLOAT = "java.lang.Float";
private static final String DATATYPE_DOUBLE = "java.lang.Double";
public static final String PRIORITY_COMPARATOR = "priority";
public static final String DISPLAY_ORDER_COMPARATOR = "displayOrder";
private enum CompareMode {EQUAL, LESS_THAN, GREATER_THAN, DEFAULT}
// generic comparator attributes
private String targetMethod;
private boolean sortAscending;
public GenericComparator(boolean sortAscending) {
super();
this.targetMethod = null;
this.sortAscending = sortAscending;
}
public GenericComparator(String sortField) {
super();
this.targetMethod = prepareTargetMethod(sortField);
this.sortAscending = true;
}
public GenericComparator(String sortField, boolean sortAscending) {
super();
this.targetMethod = prepareTargetMethod(sortField);
this.sortAscending = sortAscending;
}
/**
* {@inheritDoc}
*/
@Override
public int compare(Object o1, Object o2) {
int response = LESSER;
try {
Object v1 = (null == this.targetMethod) ? o1 : getValue(o1);
Object v2 = (null == this.targetMethod) ? o2 : getValue(o2);
CompareMode cm = findCompareMode(v1, v2);
if (!cm.equals(CompareMode.DEFAULT)) {
return compareAlternate(cm);
}
final String returnType = (null == this.targetMethod)
? o1.getClass().getName() : getMethod(o1).getReturnType().getName();
response = compareActual(v1, v2, returnType);
Logger.error("NoSuch", "" + o1.getClass().getName());
} catch (NoSuchMethodException nsme) {
Logger.error("NoSuchMethodException occurred while comparing", nsme.getMessage());
} catch (IllegalAccessException iae) {
Logger.error("IllegalAccessException occurred while comparing", iae.getMessage());
} catch (InvocationTargetException ite) {
Logger.error("InvocationTargetException occurred while comparing", ite.getMessage());
}
return response;
}
private int compareAlternate(CompareMode cm) {
int compareState = LESSER;
switch (cm) {
case LESS_THAN:
compareState = LESSER * determinePosition();
break;
case GREATER_THAN:
compareState = GREATER * determinePosition();
break;
case EQUAL:
compareState = EQUAL * determinePosition();
break;
}
return compareState;
}
private int compareActual(Object v1, Object v2, String returnType) {
int acutal = LESSER;
if (returnType.equals(DATATYPE_INTEGER)) {
acutal = (((Integer) v1).compareTo((Integer) v2) * determinePosition());
} else if (returnType.equals(DATATYPE_LONG)) {
acutal = (((Long) v1).compareTo((Long) v2) * determinePosition());
} else if (returnType.equals(DATATYPE_STRING)) {
acutal = (((String) v1).compareTo((String) v2) * determinePosition());
} else if (returnType.equals(DATATYPE_DATE)) {
acutal = (((Date) v1).compareTo((Date) v2) * determinePosition());
} else if (returnType.equals(DATATYPE_FLOAT)) {
acutal = (((Float) v1).compareTo((Float) v2) * determinePosition());
} else if (returnType.equals(DATATYPE_DOUBLE)) {
acutal = (((Double) v1).compareTo((Double) v2) * determinePosition());
}
return acutal;
}
/**
* preparing target name of getter method for given sort field
*
* @param name a {@link String}
* @return methodName a {@link String}
*/
private final static String prepareTargetMethod(String name) {
StringBuffer fieldName = new StringBuffer(METHOD_GET_PREFIX);
fieldName.append(name.substring(0, 1).toUpperCase());
fieldName.append(name.substring(1));
return fieldName.toString();
}
/**
* fetching method from <code>Class</code> object through reflect
*
* @param obj - a {@link Object} - input object
* @return method - a {@link Method}
* @throws NoSuchMethodException
*/
private final Method getMethod(Object obj) throws NoSuchMethodException {
return obj.getClass().getMethod(targetMethod, null);
}
/**
* dynamically invoking given method with given object through reflect
*
* @param method - a {@link Method}
* @param obj - a {@link Object}
* @return object - a {@link Object} - return of given method
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
private final static Object invoke(Method method, Object obj) throws InvocationTargetException, IllegalAccessException {
return method.invoke(obj, null);
}
/**
* fetching a value from given object
*
* @param obj - a {@link Object}
* @return object - a {@link Object} - return of given method
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws NoSuchMethodException
*/
private Object getValue(Object obj) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
return invoke(getMethod(obj), obj);
}
private CompareMode findCompareMode(Object o1, Object o2) {
CompareMode cm = CompareMode.LESS_THAN;
if (null != o1 & null != o2) {
cm = CompareMode.DEFAULT;
} else if (null == o1 & null != o2) {
cm = CompareMode.LESS_THAN;
} else if (null != o1 & null == o2) {
cm = CompareMode.GREATER_THAN;
} else if (null == o1 & null == o2) {
cm = CompareMode.EQUAL;
}
return cm;
}
/**
* Determining positing for sorting
*
* @return -1 to change the sort order if appropriate.
*/
private int determinePosition() {
return sortAscending ? GREATER : LESSER;
}
}
现在,要进行排序,我使用以下类:
Collections.sort(widgets, new GenericComparator("priority");
其中priority是我班级的排序顺序字段:
public class Widget实现Serializable {
private String apiId;
public String getImageLink() {
return imageLink;
}
public void setImageLink(String imageLink) {
this.imageLink = imageLink;
}
private String imageLink;
private String title;
private Integer priority;
private String description;
private String key;
public String getCta() {
return cta;
}
public void setCta(String cta) {
this.cta = cta;
}
private String cta;
public String getApiId() {
return apiId;
}
public void setApiId(String apiId) {
this.apiId = apiId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getPriority() {
return priority;
}
public void setPriority(Integer priority) {
this.priority = priority;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private int id;
public MetaData metaData = new MetaData();
public MetaData getMetaData() {
return metaData;
}
public void setMetaData(String metaData) {
Gson gson = new Gson();
this.metaData = gson.fromJson(metaData, MetaData.class);
}
public boolean isOnline() {
return isOnline;
}
public void setOnline(boolean online) {
isOnline = online;
}
private boolean isOnline;
}
但是当我运行我的apk的发布版本时,它给了我NoSuchMethodFoundException getPriority。它在调试版本中运行正常。
任何人都可以建议。这也是我的proguard配置:
-keep public class com.mypackage.GenericComparator { *; }
-keepclassmembers class com.mypackage.GenericComparator { *; }
-keep public class com.mypackage.datamodels.Widget{ *;}
-keepclassmembers class com.mypackage.datamodels.Widget{ *; }
-keep public class * extends com.mypackage.GenericComparator
-keepclassmembers class * extends com.mypackage.GenericComparator{
public <init>(java.lang.String);
}
答案 0 :(得分:0)
你能试试吗,包名可以是GenericComparator和Widget所在的包。您可以根据需要优化以下内容
-keepclassmembers class lib4.com.stackoverflow.** {
*** set*(***);
*** get*();
}