混淆后 gson 的 Proguard 错误

Posted

技术标签:

【中文标题】混淆后 gson 的 Proguard 错误【英文标题】:Proguard error with gson after obfuscation 【发布时间】:2014-03-15 01:18:10 【问题描述】:

我得到了在混淆后出现的非常具体的错误。我使用 gson 来获取用于更新程序的游戏服务器数据。

public static List<Server> getServers() 
    try 
        URL url = new URL("http://api.ensemplix.ru/v2/server/game/");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        InputStream in = conn.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(in,
                "UTF-8"));
        return Arrays.asList(gson.fromJson(br, Server[].class));
     catch (IOException e) 
        logger.warn("Failed get servers", e);
        return null;
    

在提供的数据中是表示为 ArrayList 的模组列表数组:

@SerializedName("mods")
private List<Mod> mods = new ArrayList<Mod>();

没有proguard混淆一切正常,但我得到一个收集错误:

这是它在日食中的样子:

抛出错误的方法:

    public static List<Mod> getUpdateList(ServerType serverType) 
    List<Mod> updateList = new ArrayList<Mod>();

    System.out.println(serverType.getMods().toString());

    for (Mod mod : serverType.getMods()) 
        boolean install = false;
        boolean update = false;
        boolean exists = false;

        for (LocalMod localMod : localMods) 
            if (serverType == localMod.getServerType()) 
                if (mod.getName().equalsIgnoreCase(localMod.getName())) 
                    exists = true;

                    if (!mod.getVersion().equalsIgnoreCase(
                            localMod.getVersion())) 
                        logger.info("Removing mod " + localMod.getName()
                                + " version " + localMod.getVersion()
                                + " to update to " + mod.getVersion()
                                + " in " + serverType.getName());

                        if (!localMod.getFile().delete()) 
                            throw new IllegalArgumentException(
                                    "Failed delete mod "
                                            + localMod.getName()
                                            + " "
                                            + localMod.getFile()
                                                    .getAbsolutePath());
                        

                        localMods.remove(localMod);
                        break;
                    
                
            
        

        if (!exists) 
            install = true;
        

        if (install || update) 
            if (install) 
                logger.info("Installing mod " + mod.getName() + " version "
                        + mod.getVersion() + " for " + serverType.getName());
            

            updateList.add(mod);
        
    

    return updateList;

我不知道如何修复混淆错误。你能帮忙吗?

【问题讨论】:

【参考方案1】:

有两种解决方案:

1) 您可以将@SerializedName 名称添加到您的Mod 类和其他与json 响应相关的类中。

2) 如果 Java 模型位于与您的 json 响应相关的特定包中,您可能会说 proguard 不会混淆它。正如我从您的错误日志中看到的那样;你的Mod 类被混淆了,它的名字变成了a。所以;您可以在 proguard.cfg 文件中添加如下内容:

编辑:

# Gson uses generic type information stored in a class file when working with fields.
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe  *; 

# Application classes that will be serialized/deserialized over Gson
-keep class ru.ensemplix.**  *; 

See link

【讨论】:

每个属性都有@SerializedName,在.cfg中我保持mod类不被混淆 如果您应用我的第二个建议,您将不会收到任何错误或必须更改错误消息。你试过吗? with -keep class ru.ensemlix.** *; 我有同样的问题 我已经编辑了我的答案,这是一个谷歌示例,我目前正在使用类似的示例。 嗯,我看到你的解决方案是我的第一个建议。【参考方案2】:

解决方案:

@SerializedName("mods")
private Mod[] mods;

public List<Mod> getMods() 
    return Arrays.asList(mods);

【讨论】:

以上是关于混淆后 gson 的 Proguard 错误的主要内容,如果未能解决你的问题,请参考以下文章

android中的proguard - 我应该混淆gson POJO

proguard生成的pro怎么载入

ProGuard 混淆、java、Google Gson 和泛型集合——如何留住成员?

proguard-rules.pro混淆导jar包

android中的proguard.cfg与proguard.rules.pro区别

防止 Proguard 使用注释混淆子类