2010-10-29 5 views
2

"Instanciation de classe abstraite", dites-vous. "Impossible!"Instance de classe Proguard, Android et abstraite

Voici mon code:

public static AbstractFoo getAbstractFoo(Context context) { 
    try { 
     Class<?> klass = Class 
       .forName("com.bat.baz.FooBar"); 
     Constructor<?> constructor = klass.getDeclaredConstructor(
       String.class, String.class); 
     constructor.setAccessible(true); 

     AbstractFoo foo = (AbstractFoo) constructor.newInstance(
       "1", "2"); 
     return foo; 
    } catch (ClassNotFoundException e) { 
     // Ignore 
    } catch (NoSuchMethodException e) { 
     throw new InflateException(
       "No matching constructor"); 
    } catch (IllegalAccessException e) { 
     throw new InflateException("Could not create foo", e); 
    } catch (InvocationTargetException e) { 
     throw new InflateException("Could not create foo", e); 
    } catch (InstantiationException e) { 
     throw new InflateException("Could not create foo", e); 
    } 
    return null; 
} 

com.bat.baz.FooBar est une classe privée qui étend AbstractFoo. Sans Proguard, ce code fonctionne sur mon appareil Android. Avec lui, il échoue sur le try/catch NoSuchMethodException.

Je continue à ajouter des instructions à mon fichier de configuration Proguard comme

-keep public abstract class AbstractFoo 
{public *;protected *; private *;} 

Mais cela ne résout pas le problème. Comment puis-je demander à Proguard d'accepter que c'est une manière valide d'instancier l'objet AbstractFoo? Au moins, si cela fonctionne sans Proguard, cela devrait marcher avec.

Répondre

7

ProGuard supprime le constructeur du code, car il semble inutilisé. ProGuard ne peut pas détecter que le constructeur est appelé par réflexion. Donc, vous devez garder explicitement:

-keepclassmembers class com.bat.baz.FooBar { 
    <init>(java.lang.String, java.lang.String); 
} 

S'il vous plaît noter que vous pouvez avoir de meilleures chances avec des questions comme celles-ci sur le forum d'aide de ProGuard.

0

Ajoutez-vous également des instructions pour conserver le contenu dans FooBar?

Vous pouvez utiliser "dexdump" ou "dexlist" pour voir la liste des classes et des méthodes qui sont réellement générées dans le fichier .dex. Comparer ce que vous obtenez avec et sans proguard pourrait être éclairant.

+1

Je ne l'ai pas compris en utilisant votre méthode, mais j'ai fini par découvrir ce qui se passait. J'ai inspecté mon fichier mapping.txt et trouvé que le constructeur de FooBar n'était simplement pas ajouté. Les variables ci-dessus et les méthodes en dessous étaient en cours de transformation, mais le constructeur n'était tout simplement pas là. J'essaie actuellement de comprendre pourquoi, même avec une déclaration explicite de GJTorikian

Questions connexes