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