我的应用程序有两种构建类型:debug
和release
。这是配置:
buildTypes {
release {
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
minifyEnabled true
shrinkResources true
}
debug {
debuggable true
}
}
调试编译并运行没有任何问题,但在发布时(我有minifyEnabled true
),在应用程序启动后,我得到以下异常:
09-05 15:12:42.702 29939-29939/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: ua.yyunikov.fc, PID: 29939
java.lang.RuntimeException: Unable to start activity ComponentInfo{ua.yyunikov.fc/ua.yyunikov.fc.ui.activities.RatesActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at ua.yyunikov.fc.ui.activities.BaseDrawerActivity.setupDrawer(Unknown Source)
at ua.yyunikov.fc.ui.activities.RatesActivity.initialize(Unknown Source)
at ua.yyunikov.fc.ui.activities.RatesActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
这意味着ProGuard
存在一些问题。我在使用proguard-rules.txt
文件时玩的很多,但仍然无法正常工作。这是:
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-dontwarn butterknife.internal.**
-keep class **$$ViewInjector { *; }
-keepnames class * { @butterknife.InjectView *;}
-keepattributes *Annotation*
-keep class ua.yyunikov.fc.** { *; }
-keepnames class ua.yyunikov.fc.** { *; }
-keepclassmembers class ua.yyunikov.fc.** { *; }
-keep class javax.measure.** { *; }
-keepnames class javax.measure.** { *; }
-keepclassmembers class javax.measure.** { *; }
###---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
##---------------End: proguard configuration for Gson ----------
## InMobi configuration
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient{
public *;
}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info{
public *;
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
###------------------ Configuration for Flurry -------------------- ###
-keep class com.flurry.** { *; }
-dontwarn com.flurry.**
-keepattributes *Annotation*,EnclosingMethod,Signature
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
# Google Play Services library
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
#If you are using the Google Mobile Ads SDK, add the following:
# Preserve GMS ads classes
-keep class com.google.android.gms.ads.** { *;
}
-dontwarn com.google.android.gms.ads.**
-keep public class com.google.ads.mediation.flurry.**
堆栈跟踪告诉setupDrawer()
方法存在一些问题,但我不知道是什么问题。这是方法:
protected void setupDrawer() {
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
final NavigationDrawerAdapter adapter = new NavigationDrawerAdapter(this);
adapter.add(new DrawerItemPrimary(getString(R.string.dashboard_activity_title),
ResourceUtil.resolveAttributeToResourceId(getTheme(), R.attr.ic_dashboard)));
adapter.add(new DrawerItemPrimary(getString(R.string.rates_activity_title),
ResourceUtil.resolveAttributeToResourceId(getTheme(), R.attr.ic_rates)));
adapter.add(new DrawerItemPrimary(getString(R.string.counter_activity_title),
ResourceUtil.resolveAttributeToResourceId(getTheme(), R.attr.ic_calculator)));
adapter.add(new DrawerItemPrimary(getString(R.string.foods_activity_title),
ResourceUtil.resolveAttributeToResourceId(getTheme(), R.attr.ic_food)));
adapter.add(new DrawerItemPrimary(getString(R.string.calculators_activity_title),
ResourceUtil.resolveAttributeToResourceId(getTheme(), R.attr.ic_percent)));
adapter.add(new DrawerItemDivider());
adapter.add(new DrawerItemSecondary(getString(R.string.settings_activity_title),
ResourceUtil.resolveAttributeToResourceId(getTheme(), R.attr.ic_settings)));
adapter.add(new DrawerItemSecondary(getString(R.string.about_activity_title),
ResourceUtil.resolveAttributeToResourceId(getTheme(), R.attr.ic_help)));
/* adapter.add(new DrawerItemSecondary(getString(R.string.notes_activity_title),
ResourceUtils.resolveAttributeToResourceId(getTheme(), R.attr.ic_notes)));*/
mDrawerList.setAdapter(adapter);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener(this));
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar applicaion icon
mDrawerToggle =
new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.string.no_text, // "open drawer" description for accessibility
R.string.no_text // "close drawer" description for accessibility
) {
public void onDrawerClosed(View view) {
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
setupActionBar();
isDrawerOpened = false;
}
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
showDefaultActionBar();
isDrawerOpened = true;
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
为什么会出现这个问题以及如何解决这个问题?
答案 0 :(得分:1)
太奇怪了,但将SDK版本从23级降级到22级再次解决了这个问题:
targetSdkVersion = 22
compileSdkVersion = 22
buildToolsVersion = "22.0.0"