Android 启用Proguard时解组时找不到类

Android 启用Proguard时解组时找不到类,android,proguard,parcelable,Android,Proguard,Parcelable,我一直在处理Proguard配置问题。我的应用程序在调试时工作正常,但发布的apk在启动第二个活动时给了我一个异常。这似乎发生在试图从Intent中检索可包裹的额外物品时 以下是stacktrace: E/Parcel﹕ Class not found when unmarshalling: com.mycompany.model.Task java.lang.ClassNotFoundException: com.mycompany.model.Task at

我一直在处理Proguard配置问题。我的应用程序在调试时工作正常,但发布的apk在启动第二个活动时给了我一个异常。这似乎发生在试图从Intent中检索可包裹的额外物品时

以下是stacktrace:

E/Parcel﹕ Class not found when unmarshalling: com.mycompany.model.Task
    java.lang.ClassNotFoundException: com.mycompany.model.Task
            at java.lang.Class.classForName(Native Method)
            at java.lang.Class.forName(Class.java:251)
            at java.lang.Class.forName(Class.java:216)
            at android.os.Parcel.readParcelableCreator(Parcel.java:2133)
            at android.os.Parcel.readParcelable(Parcel.java:2097)
            at android.os.Parcel.readValue(Parcel.java:2013)
            at android.os.Parcel.readArrayMapInternal(Parcel.java:2314)
            at android.os.Bundle.unparcel(Bundle.java:249)
            at android.os.Bundle.getString(Bundle.java:1118)
            at android.content.Intent.getStringExtra(Intent.java:5128)
            at com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:1447)
            at com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:1043)
            at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:4054)
            at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:3948)
            at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:159)
            at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2629)
            at android.os.Binder.execTransact(Binder.java:404)
            at dalvik.system.NativeStart.run(Native Method)
Caused by: java.lang.NoClassDefFoundError: com/mycompany/model/Task
            at java.lang.Class.classForName(Native Method)
            at java.lang.Class.forName(Class.java:251)
            at java.lang.Class.forName(Class.java:216)
            at android.os.Parcel.readParcelableCreator(Parcel.java:2133)
            at android.os.Parcel.readParcelable(Parcel.java:2097)
            at android.os.Parcel.readValue(Parcel.java:2013)
            at android.os.Parcel.readArrayMapInternal(Parcel.java:2314)
            at android.os.Bundle.unparcel(Bundle.java:249)
            at android.os.Bundle.getString(Bundle.java:1118)
            at android.content.Intent.getStringExtra(Intent.java:5128)
            at com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:1447)
            at com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:1043)
            at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:4054)
            at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:3948)
            at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:159)
            at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2629)
            at android.os.Binder.execTransact(Binder.java:404)
            at dalvik.system.NativeStart.run(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.mycompany.model.Task" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
            at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:67)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
            at java.lang.Class.classForName(Native Method)
            at java.lang.Class.forName(Class.java:251)
            at java.lang.Class.forName(Class.java:216)
            at android.os.Parcel.readParcelableCreator(Parcel.java:2133)
            at android.os.Parcel.readParcelable(Parcel.java:2097)
            at android.os.Parcel.readValue(Parcel.java:2013)
            at android.os.Parcel.readArrayMapInternal(Parcel.java:2314)
            at android.os.Bundle.unparcel(Bundle.java:249)
            at android.os.Bundle.getString(Bundle.java:1118)
            at android.content.Intent.getStringExtra(Intent.java:5128)
            at com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:1447)
            at com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:1043)
            at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:4054)
            at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:3948)
            at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:159)
            at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2629)
            at android.os.Binder.execTransact(Binder.java:404)
            at dalvik.system.NativeStart.run(Native Method)
存在可包裹任务模型:

public class Task implements Parcelable {

    public enum Mode {MODE1, MODE2}

    public enum Type {TYPE1, TYPE2, TYPE3}

    private final String id;
    private final Mode mode;
    private final Type type;
    private ArrayList<Character> charactersList;

    public Task(String id, ArrayList<Character> characters, Mode mode, Type type) {
        this.id = id;
        this.charactersList = characters;
        this.mode = mode;
        this.type = type;
    }

    public Mode getMode() {
        return mode;
    }

    public Type getType() {
        return type;
    }

    public String getId() {
        return id;
    }

    public ArrayList<Character> getCharactersList() {
        return charactersList;
    }

    private Task(Parcel in) {
        id = in.readString();

        Parcelable[] parcelablecharactersArray = in.readParcelableArray(Character.class.getClassLoader());
        charactersList = new ArrayList<>();
        for (Parcelable p : parcelablecharactersArray) {
            charactersList.add((Character) p);
        }

        mode = Mode.valueOf(in.readString());
        type = Type.valueOf(in.readString());

    }

    public static final Parcelable.Creator<Task> CREATOR = new Parcelable.Creator<Task>() {

        public Task createFromParcel(Parcel in) {
            return new Task(in);
        }

        public Task[] newArray(int size) {
            return new Task[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(id);
        dest.writeParcelableArray(charactersList.toArray(new Parcelable[charactersList.size()]), 0);
        dest.writeString(mode.name());
        dest.writeString(type.name());

    }

}
以及proguard规则:

-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keep public class com.mycompany.model.Task { *; }
-keep public class com.mycompany.model.Character { *; }
-keep public class com.mycompany.Constants { *; }

你知道问题出在哪里吗?我的第一个猜测是,当试图在Parcelable构造函数中创建Character ArrayList时,classloader出现了问题(顺便说一下,Character也实现了Parcelable)。第二个猜测是枚举。

我认为问题来自
Parcelable
它扩展了
Task

# could be refined, but if it works you got the idea
-keepnames class * implements android.os.Parcelable { *; }
-keepclassmembers class * implements android.os.Parcelable { *; }
-keep public class com.mycompany.model.Task { *; }

我认为问题来自
Parcelable
,它扩展了
Task

# could be refined, but if it works you got the idea
-keepnames class * implements android.os.Parcelable { *; }
-keepclassmembers class * implements android.os.Parcelable { *; }
-keep public class com.mycompany.model.Task { *; }

找到了答案。这是一个Proguard配置。但这并不是关于Parcelable或Task,而是关于另一个模块中的其他类,这些类被混淆了,不应该被混淆

添加

-keep public class com.othermodule.OtherClass { *; }
成功了

所以stacktrace有点误导,或者至少不够明确


无论如何,谢谢@shkschneider的帮助。

找到了答案。这是一个Proguard配置。但这并不是关于Parcelable或Task,而是关于另一个模块中的其他类,这些类被混淆了,不应该被混淆

添加

-keep public class com.othermodule.OtherClass { *; }
成功了

所以stacktrace有点误导,或者至少不够明确


无论如何,谢谢@shkschneider的帮助。

我也有同样的问题,你能告诉我们你是如何解决的吗。与任务或包裹无关。首先尝试使用更宽松的规则,看看它是否能解决您的问题。然后你可以让他们更严格。希望有帮助!我也有同样的问题,你能告诉我们你是如何解决的吗?就像我在帖子中说的,我必须找出哪些类被错误地混淆了。与任务或包裹无关。首先尝试使用更宽松的规则,看看它是否能解决您的问题。然后你可以让他们更严格。希望有帮助!