NullPointerException при использовании XML-файла в res/raw с Proguard
Я использую простой XML-сериализатор в своем приложении и, кажется, успешно исключил его из обфускации Proguard, используя следующие строки в proguard.cfg, благодаря этому вопросу SO:
-keep public class org.simpleframework.**{ *; }
-keep class org.simpleframework.xml.**{ *; }
-keep class org.simpleframework.xml.core.**{ *; }
-keep class org.simpleframework.xml.util.**{ *; }
Я могу подписать и экспортировать apk, но когда я пытаюсь запустить свое приложение, оно вылетает с NullPointerException при попытке доступа к XML-файлу в каталоге res/raw (R.raw.home_screen_menu).
Я исключаю R.java с этим:
-keepclassmembers class **.R$* {
public static <fields>;
}
Я играл с этим файлом конфигурации весь день, но безуспешно. Кто-нибудь сталкивался с этой проблемой или как-то так? Последнее, что я попробовал, - это использование параметров "adaptresource", как показано ниже:
-adaptresourcefilenames **.xml
-adaptresourcefilecontents **.xml
Для справки, вот содержимое моего proguard.cfg:
#Use 5 step of optimization
-optimizationpasses 5
#When not preverifing in a case-insensitive filing system, such as Windows. This tool will unpack your processed jars,(if using windows you should then use):
-dontusemixedcaseclassnames
#Specifies not to ignore non-public library classes. As of version 4.5, this is the default setting
-dontskipnonpubliclibraryclasses
#Preverification is irrelevant for the dex compiler and the Dalvik VM, so we can switch it off with the -dontpreverify option.
-dontpreverify
#Specifies to write out some more information during processing. If the program terminates with an exception, this option will print out the entire stack trace, instead of just the exception message.
-verbose
#The -optimizations option disables some arithmetic simplifications that Dalvik 1.0 and 1.5 can't handle. Note that the Dalvik VM also can't handle aggressive overloading (of static fields).
#To understand or change this check http://proguard.sourceforge.net/index.html#/manual/optimizations.html
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-dump ../bin/class_files.txt
-printseeds ../bin/seeds.txt
-printusage ../bin/unused.txt
-printmapping ../bin/mapping.txt
-dontskipnonpubliclibraryclassmembers
#Ignore warnings for roboguice.activity.RoboAccountAuthenticatorActivity
-dontwarn roboguice.activity.RoboAccountAuthenticatorActivity
-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
-keep public class com.android.vending.licensing.ILicensingService
-keep class com.google.inject.Binder
# Keep annotations
-keepattributes *Annotation*
-keepattributes Signature
#To remove debug logs:
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** w(...);
}
# Roboguice
-keepclassmembers class * {
@com.google.inject.Inject <init>(...);
}
# SimpleXML
-keep public class org.simpleframework.**{ *; }
-keep class org.simpleframework.xml.**{ *; }
-keep class org.simpleframework.xml.core.**{ *; }
-keep class org.simpleframework.xml.util.**{ *; }
-dontwarn javax.xml.stream.**
-dontwarn javax.xml.namespace.**
-keep public class roboguice.**
# There's no way to keep all @Observes methods, so use the On*Event convention to identify event handlers
-keepclassmembers class * {
void *(**On*Event);
}
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}
-keepclasseswithmembers 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 enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class * implements android.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
2 ответа
Оказывается, сырые файлы остались одни и все в порядке. Проблема заключалась в том, что мой класс использовался для сериализации с аннотациями для сериализатора Simple XML. Я добавил операторы журнала в свое приложение и обнаружил эту ошибку в ошибочной строке: "У атрибута 'id' нет совпадения в классе com.xxx.ListViewItems в строке 2". Это заставило меня понять, что закрытая переменная "id" была запутана и не распознавалась сериализатором Simple XML. Вот код из ListViewItems.java:
@Attribute(required=false)
private String id; // This was being obfuscated and thus unrecognizable!
Вот что я добавил в Proguard, чтобы полностью пропустить запутывание класса (возможно, есть лучший способ):
# Ignore our XML Serialization classes
-keep public class com.xxx.ListViewItems {
public protected private *;
}
У меня точно такая же проблема. Наконец я решаю это благодаря этому вопросу и ответу. Я оставил здесь окончательную конфигурацию:
build.gradle:
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dependencies {
compile('org.simpleframework:simple-xml:2.7.1') {
exclude module: 'stax'
exclude module: 'stax-api'
exclude module: 'xpp3'
}
}
proguard-rules.pro (дополнение к конфигурации по умолчанию для proguard)
-dontwarn javax.xml.**
-keep public class org.simpleframework.**{ *; }
-keep class org.simpleframework.xml.**{ *; }
-keep class org.simpleframework.xml.core.**{ *; }
-keep class org.simpleframework.xml.util.**{ *; }
-keepattributes Signature
-keepattributes *Annotation*
# Ignore our XML Serialization classes
-keep public class your.annotated.pojo.models.*{
public protected private *;
}
Надеюсь, это кому-нибудь поможет