You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用ProGuard后JSON解析异常:物理设备数据显示为0

问题描述

启用ProGuard后出现JSON解析异常:原本tx1控件应显示数字9,但物理Android设备上显示0,而AVD(安卓虚拟设备)开启ProGuard仍能正常显示9。

相关代码

MainActivity.java

package com.alamart;

import android.content.Context;
import android.os.Bundle;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity {
    private TextView tx1;
    private TextView tx2;
    private String json;
    private ArrayList<HashMap<String, Object>> map = new ArrayList<>();
    public ArrayList<HashMap<String, Object>> jumlahBarang = new ArrayList<>();
    private GetSize getSize;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        try {
            InputStream is = MainActivity.this.getAssets().open("1.json");
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
            json = new String(buffer, "UTF-8");
            map = new Gson().fromJson(json, new TypeToken<ArrayList<HashMap<String, Object>>>() {
            }.getType());
            for (HashMap<String, Object> item : map) {
                HashMap<String, Object> newItem = new HashMap<>();
                newItem.put("coklat", item.get("coklat"));
                jumlahBarang.add(newItem);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        tx1 = findViewById(R.id.tx1);
        tx1.setText(String.valueOf(jumlahBarang.size()));

        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
    }
}

build.gradle中的buildTypes配置

buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
原因分析
  • ProGuard激进优化破坏Gson解析:你使用的proguard-android-optimize.txt包含更严格的代码优化规则,物理设备上ProGuard可能对HashMap、TypeToken相关代码进行了过度混淆/优化,导致Gson无法识别泛型类型,JSON解析失败,最终jumlahBarang为空列表,显示0。
  • AVD与物理设备的编译差异:AVD的运行环境可能默认跳过了部分ProGuard优化,或者JIT编译逻辑不同,使得优化后的代码仍能正常执行;而物理设备的AOT编译会应用完整优化规则,触发了解析异常。
  • 异常被静默处理:代码中用catch (Exception e)捕获所有异常但仅打印堆栈,没有暴露解析失败的具体问题,增加了排查难度。
解决方法

1. 添加Gson专属ProGuard规则

在proguard-rules.pro文件中添加以下规则,防止Gson相关类和泛型解析逻辑被破坏:

# 保留Gson核心类与特性
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.google.gson.** { *; }
-keep class com.google.gson.stream.** { *; }

# 保留TypeToken的匿名子类(泛型解析依赖)
-keepclassmembers class * extends com.google.gson.reflect.TypeToken {
    <init>(...);
}

# 防止HashMap结构被优化
-keepclassmembers class java.util.HashMap {
    <fields>;
    <methods>;
}

2. 替换保守的ProGuard配置文件

如果proguard-android-optimize.txt的激进优化引发问题,可以换成默认的保守配置:

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

3. 暴露异常信息以便排查

修改catch块,将异常信息可视化,快速定位问题:

catch (Exception e) {
    e.printStackTrace();
    tx1.setText("解析失败: " + e.getMessage());
}

4. 验证JSON文件完整性

解压物理设备上的APK,检查assets/1.json文件是否完整、内容是否正确,避免文件被压缩或损坏导致解析失败。

内容的提问来源于stack exchange,提问作者Muspedia indonesia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:12:48