21

私はAndroidプロジェクトでsimplexmlを使用していますが、コードを難読化するまですべてが正常に機能します。次に、エラーが発生し始めます。

XMLの一部は次のとおりです。

<categories success="true">
  <category id="102" caption="Magazin" parent="0" num_mags="114" >
    <category id="15" caption="Kunst" parent="102" num_mags="13" >
      <category id="17" caption="Design" parent="15" num_mags="10" ></category>
      <category id="18" caption="Haute+Couture" parent="15" num_mags="2" >
...

私には2つのクラスがあります:CategoryItemList:

@Root(name = "categories")
public class CategoryItemList {

    private final List<CategoryItem> mCategoryItems;
    /**
     * Create a new category items list.
     * 
     * @param categoryItems the list of category items
     */
    public CategoryItemList(@ElementList(name = "category", inline = true) final List<CategoryItem> categoryItems) {
        mCategoryItems = categoryItems;
    }
    @ElementList(name = "category", inline = true)
    public List<CategoryItem> getCategoryItems() {
        return mCategoryItems;
    }
}

およびCategoryItem:

@Root(name = "category")
public class CategoryItem {
    private final int mId;
    private final String mCaption;
    private final int mParent;
    private final int mNumberOfMagazines;
    private final ArrayList<CategoryItem> mSubCategoryItems;
    /**
     * Creating a new category item.
     * 
     * @param id the category id
     * @param caption the name of category
     * @param parent the parent category
     * @param numMags the number of magazines from that category
     */
    public CategoryItem(@Attribute(name = "id") final int id,
                        @Attribute(name = "caption") final String caption,
                        @Attribute(name = "parent") final int parent,
                        @Attribute(name = "num_mags") final int numMags,
                        @ElementList(name = "category", inline = true, required = false) final ArrayList<CategoryItem> subCategoryItems) {
        mId = id;
        mCaption = caption;
        mParent = parent;
        mNumberOfMagazines = numMags;
        mSubCategoryItems = subCategoryItems;
    }

    @Attribute(name = "id")
    public int getId() {
        return mId;
    }

    @Attribute(name = "caption")
    public String getCaption() {
        String categoryName = null;

        try {
            categoryName = URLDecoder.decode(mCaption, "UTF-8");
        } catch (final UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return categoryName;
    }

    @Attribute(name = "parent")
    public int getParentId() {
        return mParent;
    }

    @Attribute(name = "num_mags")
    public int getNumbersOfMagazines() {
        return mNumberOfMagazines;
    }

    @ElementList(name = "category", inline = true, required = false)
    public ArrayList<CategoryItem> getSubCategory() {
        return mSubCategoryItems;
    }
}

ここで、コードを難読化するときに、「-keepattributes Annotation」を省略すると、PersistenceException:コンストラクターがクラスに一致しません。

これを含めると、「コンストラクターのパラメーター1のジェネリック型を判別できません」という例外が発生します。これらはすべて実行時に発生します。
ご覧のとおり、名前はそこにあり、クラス全体で名前を保持しようとしましたが、まったく役に立ちませんでした。

simplexmlで動作するようにProguardを構成するにはどうすればよいですか?

編集:私のproguard.cfgファイルは次のとおりです:(私が試したすべてのものが少し詰まっていますが、これは現在のバージョンです)

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-printseeds
-dontoptimize
-keepattributes *Annotation*
-keepattributes EnclosingMethod

-libraryjars <java.home>/lib/rt.jar (javax/xml/stream/** )

-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

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

-dontwarn android.support.**,de.greenrobot.**,org.simpleframework.xml.**
-keep class com.crittercism.**{ *; }
-keepclassmembernames class com.crittercism.**{ *; }
-keepclasseswithmembers class com.crittercism.**{ *; }

-keep class org.simpleframework.**{ *; }
-keepclassmembernames class org.simpleframework.**{ *; }
-keepclasseswithmembers class org.simpleframework.**{ *; }

-keep class crittercism.android.**
-keepclassmembers public class com.crittercism.*{ *;}

-keep public class database.** {
    public static <fields>;
}

-keep class android.support.**
-keepclasseswithmembers class android.support.** { *;}

-keep class org.simpleframeork.**
-keepclasseswithmembers class org.simpleframeork.** { *;}

-keep class javax.**
-keepclasseswithmembers class javax.** { *;}

-keep class com.test.category.**
-keepclassmembernames class com.test.category.** { *; }
-keepclasseswithmembers class com.test.category.** { *;}

-keep class com.test.download.**
-keepclassmembernames class com.test.download.** { *; } 
-keepclasseswithmembers class com.test.download.** { *;}

-keep class org.simpleframework.**{ *; } 
-keep class org.simpleframework.xml.**{ *; } 
-keep class org.simpleframework.xml.core.**{ *; } 
-keep class org.simpleframework.xml.util.**{ *; }
-keep class org.simpleframework.xml.stream.**{ *; }

-keepclassmembers class * implements java.io.Serializable {
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
4

7 に答える 7

7

注釈を保持することは良い考えであることはすでに理解しています。@ElementListアノテーションに型パラメーターを追加することもできます-明らかにジェネリック型消去に問題があり、simplexmlにはリスト内の要素の型に関する追加のヒントが必要です

-keepattributes署名、*注釈*を試してみることもできます。

「Signature」属性は、JDK5.0以降でコンパイルするときにジェネリック型にアクセスできるようにするために必要です。

于 2012-09-06T08:14:46.933 に答える
7

SimpleXMLライブラリを使用してコードを難読化する場合の問題は、次のとおりです。

  1. エンティティの「注釈」と「署名」を保持する必要があります

    @Attribute(name = "retcode"、required = true)private String _retcode;

  2. SimpleXMLライブラリを保持する必要があります

  3. コードの特定のブロックが削除されないようにする必要があります。たとえば、エンティティのコンストラクターが使用されていない場合、proguardはそれを削除しますが、そのメソッドはSimpleXMLLibraryで内部的に使用できます。

proguard.cfgファイルは次のようになります。

# The following line may be different
-libraryjars <java.home>/lib/rt.jar(java/**,javax/**)

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
# (3)Not remove unused code
-dontshrink

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-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
# (2)Simple XML
-keep public class org.simpleframework.**{ *; } 
-keep class org.simpleframework.xml.**{ *; } 
-keep class org.simpleframework.xml.core.**{ *; } 
-keep class org.simpleframework.xml.util.**{ *; }
# (1)Annotations and signatures
-keepattributes *Annotation*
-keepattributes Signature

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

私は自分のプロジェクトでそれを使用し、それは機能します;)

于 2013-01-22T11:59:01.623 に答える
4

プロジェクトのSubversionリポジトリからの公式のものを使用してください。

https://simple.svn.sourceforge.net/svnroot/simple/trunk/download/stream/proguard.pro

于 2013-03-05T10:03:21.717 に答える
2

Eclipseでプロジェクトを右クリックします。androidに移動->Lintを実行します。

Lintには、プロガードの設定ミスをチェックする機能があり、エラーを検出して説明する場合があります。

于 2012-08-31T20:25:50.783 に答える
2

次のエラーが発生し続けました。

can't find referenced class javax.xml.stream.XMLEventReader

can't find referenced class javax.xml.stream.events.XMLEvent

これは、これらがJavaランタイム(rt.jar)の一部であり、Androidランタイム(android.jar)の一部ではないためです。そのため、ProGuardは何かが壊れている可能性があることを警告します。これは実際には問題ではないので、次のことができます。

-dontwarn javax.xml.stream.events.**

ソース

zmicerの答えと組み合わせると、次のようになります

-dontwarn javax.xml.stream.events.**

-keep public class org.simpleframework.** { *; }
-keep class org.simpleframework.xml.** { *; }
-keep class org.simpleframework.xml.core.** { *; }
-keep class org.simpleframework.xml.util.** { *; }

-keepattributes ElementList, Root

-keepclassmembers class * {
    @org.simpleframework.xml.* *;
}
于 2016-01-25T10:55:08.453 に答える
1

これをproguardファイルに追加してみてください。

-keep public class org.simpleframework.** { *; }
-keep class org.simpleframework.xml.** { *; }
-keep class org.simpleframework.xml.core.** { *; }
-keep class org.simpleframework.xml.util.** { *; }

-keepattributes ElementList, Root

-keepclassmembers class * {
    @org.simpleframework.xml.* *;
}

これで修正されました。

于 2014-05-08T12:31:44.713 に答える
1

proguardファイルへのこの正確な追加は私のために働きました:

-dontwarn javax.xml.stream.**

-keep public class org.simpleframework.** { *; }
-keep class org.simpleframework.xml.** { *; }
-keep class org.simpleframework.xml.core.** { *; }
-keep class org.simpleframework.xml.util.** { *; }

-keepattributes ElementList, Root

-keepclassmembers class * {
    @org.simpleframework.xml.* *;
}
于 2017-05-24T08:06:49.757 に答える