Я распространил приложение на Android Marketplace. Я получаю отчеты об ошибках от небольшой группы пользователей (возможно, 2%), где они получают исключения NullPointerExceptions, где это не имеет логического смысла.
Мне никогда не удавалось повторить это самому. Код относительно прост и представляет собой общий путь кода, которому должен следовать КАЖДЫЙ пользователь. На самом деле я взял каждую отдельную строку кода, которая могла бы создать NPE, и заключил ее в блок try-catch и выбросил настраиваемое исключение времени выполнения, но я все еще получаю не обнаруженные ошибки NullPointerException.
На данный момент единственное, что я могу представить, это что-то связанное с моей обфускацией Proguard. Я видел другую статью, в которой говорилось об отключении опции -overloadaggressively, если вы заметили странное поведение, но, насколько я могу судить, я не использую эту опцию.
Кто-нибудь еще испытывал таинственные NPE с использованием android и proguard. Есть ли какие-то другие настройки, которые люди могут порекомендовать, чтобы уменьшить количество оптимизаций, которые могут вызвать эту проблему?
Есть другие идеи?
Для справки, вот не запутанная функция, которая получает 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();
}
Итак, единственный Возможности, которые я вижу, это игра, диспетчер и настройки.
игра устанавливается с помощью этого кода в другом классе. game - последняя переменная в этом другом классе: диспетчер
game.setScreen(new MainMenuScreen(game));
устанавливается внутри в вызове super выше.
getSettings () возвращает объект настроек, который устанавливается в самом начале приложения, является частным и никогда не сбрасывается. Его также использовали перед этим методом несколько раз.
Нет примитивов автобокса.
вот конфиг прогарда:
-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 *;
}