Ho distribuito un'applicazione sul Marketplace Android. Ricevo nuovamente segnalazioni di errori da una manciata di utenti (forse il 2%) dove stanno ottenendo NullPointerExceptions dove non ha senso logico.Il codice offuscato proguard Android sta causando NullPointerException quando non dovrebbe essere
Non sono mai stato in grado di replicare da solo. Il codice è relativamente semplice ed è un percorso di codice comune che OGNI utente deve seguire. In realtà ho preso ogni singola riga di codice che potrebbe creare l'NPE e l'ho racchiusa in un blocco try-catch e lanciare un'eccezione di runtime personalizzata, ma sto ancora ricevendo errori di NullPointerException non rilevati.
A questo punto, l'unica cosa che posso immaginare sarebbe qualcosa che riguarda la mia confusione Proguard. Ho visto qualche altro articolo che parla dell'eliminare l'opzione -overloadaggressively se si nota un comportamento strano, ma per quanto posso dire, non sto usando questa opzione.
Qualcun altro ha sperimentato misteriosi NPE utilizzando Android e proguard. Esistono altre impostazioni che le persone possono consigliare per azzerare le ottimizzazioni che potrebbero causare questo problema?
Altre idee?
Per avere un riferimento, qui è la funzione unobfuscated che sta ottenendo la NPE:
public MainMenuScreen(final HauntedCarnival game) {
super(game);
game.startMusic("data/music/intro.mp3");
stage = new Stage(Screen.SCREEN_WIDTH, Screen.SCREEN_HEIGHT,true);
stage.addActor(new Image("background", Assets.mainMenuBackground));
Image title = new Image("title", Assets.mainMenuTitle);
title.x = 0;
title.y = 340;
resetEyeBlink();
stage.addActor(title);
dispatcher.registerInputProcessor(stage);
settings = game.getSettings();
eyeBlinkImage = new Image("eyeBlink", Assets.eyeBlink);
if (settings.getPlayers().isEmpty()) {
settings.addPlayer("Player One");
settings.save(game);
}
setupContinue();
}
così l'unica possibilità che vedo sono gioco, dispatcher e le impostazioni.
il gioco viene impostato tramite questo codice in un'altra classe. gioco è una variabile finale che altra classe:
game.setScreen(new MainMenuScreen(game));
dispatcher viene impostata all'interno nella chiamata a super sopra.
getSettings() restituisce un oggetto impostazioni che viene impostato all'inizio dell'applicazione, privato e mai disinserito. È anche usato prima di questo metodo più volte.
Non ci sono primitive di auto-boxing.
qui è il config Proguard:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keepattributes Signature
-keep public class com.alkilabs.hauntedcarnival.settings.Settings
-keep public class com.alkilabs.hauntedcarnival.settings.Settings {
*;
}
-keep public class com.alkilabs.hauntedcarnival.settings.Player
-keep public class com.alkilabs.hauntedcarnival.settings.Player {
*;
}
-keepnames public class com.alkilabs.hauntedcarnival.world.World
-keepnames public class * extends com.alkilabs.hauntedcarnival.world.upgrades.Upgrade
-keepnames public class * extends com.alkilabs.hauntedcarnival.world.achievments.Achievement
-keepnames public class com.alkilabs.hauntedcarnival.world.monsters.MonsterType
-keepclassmembers class * extends com.alkilabs.hauntedcarnival.world.monsters.Monster {
public <init>(com.alkilabs.hauntedcarnival.world.monsters.MonsterType, java.lang.Integer, com.alkilabs.hauntedcarnival.world.World);
}
-keepnames public class com.alkilabs.hauntedcarnival.world.items.ItemType
-keepclassmembers class * extends com.alkilabs.hauntedcarnival.world.items.Item {
public <init>(com.alkilabs.hauntedcarnival.world.World, java.lang.Integer, java.lang.Integer);
}
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-dontwarn com.badlogic.gdx.scenes.scene2d.ui.utils.DesktopClipboard
-dontwarn com.badlogic.gdx.utils.JsonWriter
-dontwarn com.badlogic.gdx.utils.XmlWriter
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
È possibile inserire il codice che causa le impostazioni NPE e ProGuard utilizzate? – Idolon
Ho aggiunto ulteriori dettagli sul codice specifico e sulla mia proguard config – Paul