Android clazz.getConstructors()返回错误数量的构造函数,仅在实时应用程序中

时间:2014-08-10 23:50:42

标签: java android reflection constructor

我有一堂课WifiScanning:

public class WifiScanning extends AbstractSetting {


/**
 * 
 */
private static final long serialVersionUID = 226897434530036069L;


public WifiScanning(Object valueToApply) {
    super(valueToApply, WifiScanning.class);
}

/**
 * For persistence only
 */
public WifiScanning() {
    super(null, WifiScanning.class);
}

如您所见,它有2个构造函数。一个是我的简单持久层,是一个空构造函数,所以newInstance()工作,另一个接受一个参数,这是我的应用程序定义的标准。其他代码假定必须有一个带有单个参数的构造函数,否则会引发异常。

/**
 * 
 * @param setting
 * @param ctx
 * @return
 * @throws SettingException
 */
private synchronized static AbstractSetting getOriginalSetting(AbstractSetting setting, 
        Context ctx) throws SettingException {

    Class<? extends AbstractSetting> clazz = setting.getClass();
    try {
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        for (Constructor<?> c : constructors) {
            if(c.getParameterTypes().length == 1) {
                Object original = setting.getCurrentSettingValue(ctx);
                LOG.debug("Caching original value '"+original+"' for "+clazz.getSimpleName());
                return (AbstractSetting) c.newInstance(original);
            }
        }

        /*
         * ###################### DEBUG BLOCK ######################
         * 
         * This has been put here to work out why we are getting to this point in the code when
         * using WifiScanning.java
         */
        LOG.error("There are "+constructors.length+" constructors for "+clazz.getName()+" which we got from "+setting);
        for (Constructor<?> c : constructors) {
            if(c.getParameterTypes().length == 1) {
                LOG.debug("Found the consructor! How the hell can that be?");
            }
            else {
                LOG.error("Unusable constructor: "+c.toGenericString());
                LOG.error("From: "+c.getDeclaringClass());
                LOG.error("Modifiers:");
                LOG.error("private="+Modifier.isPrivate(c.getModifiers()));
                LOG.error("protected="+Modifier.isProtected(c.getModifiers()));
                LOG.error("public="+Modifier.isPublic(c.getModifiers()));
                LOG.error("static="+Modifier.isStatic(c.getModifiers()));

                Type[] genericParameterTypes = c.getGenericParameterTypes();
                LOG.error("Constructor has "+genericParameterTypes.length+" generic parameter types");
                for (Type type : genericParameterTypes) {
                    LOG.error("Generic parameter type: "+type.getClass().getName());
                }

                Class<?>[] parameterTypes = c.getParameterTypes();
                LOG.error("Constructor has "+parameterTypes.length+" parameters");
                for (Class<?> arg1 : parameterTypes) {
                    LOG.error("Constructor arg: "+arg1.getName());
                }
            }
        }
        /*
         * ###################### END DEBUG BLOCK ######################
         */

        throw new SettingException(clazz+" does not have a constructor with a single argument");

如果您考虑上面的代码,则添加DEBUG BLOCK以尝试了解此处发生的情况。如果你暂时忽略它,那么你所拥有的是一段代码块,它从代码中获取构造函数数组并迭代它们,寻找具有单个参数的构造函数。如果循环退出但没有找到,则抛出异常。

使用添加的异常块,日志显示:

  

E / Proference:10/7 22:28:59.917 e.b [126]:有1个构造函数用于   com.domloge.proference.setting.WifiScanning我们得到了   WifiScanning&#34;测试&#34; [set:true | current:false | priority:1] E / Proference:   10/7 22:28:59.917 e.b [132]:不可用的构造函数:public   com.domloge.proference.setting.WifiScanning()V / Proference:清除   日志文件E / Proference:10/7 22:28:59.918 e.b [133]:来自:课堂   com.domloge.proference.setting.WifiScanning E / Proference:10/7   22:28:59.919 e.b [134]:修饰语:E / Proference:10/7 22:28:59.919   e.b [135]:private = false E / Proference:10/7 22:28:59.920 e.b [136]:   protected = false E / Proference:10/7 22:28:59.920 e.b [137]:public = true   E / Proference:10/7 22:28:59.920 e.b [138]:static = false E / Proference:   10/7 22:28:59.921 e.b [141]:构造函数有0个通用参数类型   E / Proference:10/7 22:28:59.921 e.b [147]:构造函数有0个参数   E / Proference:10/7 22:28:59.922 j.b [270]:无法申请

正如您所看到的,VM显示WifiScanning类正在提供一个构造函数,而不是2.这怎么可能?

当我在我的个人设备和各种模拟器上运行代码时,这不是问题,并且阵列中有2个构造函数。

问题是,当应用通过Google Play商店分发时,该数组包含一个构造函数。我在谷歌Play商店发布应用时无法调试我的应用,我只能查看日志。

这个相同的主体在应用程序中有超过10个其他类正常工作......但是这个正在起作用......好像有一个我错过的拼写错误,这将是一个额头拍打哦!哦!有人指出我愚蠢的错误的那一刻...

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

是的,这显然是预言&#34; michief&#34;。

将以下行放在proguard-project.txt

-keepclassmembers class * extends full-package-name.AbstractSetting {
    public protected <init>(...);
} 

你会好好的。