Proguard问题:尝试在空对象引用上调用虚方法'void android.widget.ListView.setAdapter(android.widget.ListAdapter)'

时间:2015-09-05 12:48:02

标签: java android proguard android-proguard

我的应用程序有两种构建类型:debugrelease。这是配置:

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);
    }

为什么会出现这个问题以及如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

太奇怪了,但将SDK版本从23级降级到22级再次解决了这个问题:

targetSdkVersion = 22
compileSdkVersion = 22
buildToolsVersion = "22.0.0"