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

Retrofit onResponse未执行仅onFailure触发,图表数据请求失败求助

Retrofit请求进入onFailure的问题排查与修复

核心问题分析

  1. JSON结构与接口返回类型不匹配
    接口返回的是JSON数组([]包裹),但你定义的init()方法返回Call<ChartResponse>,单个对象无法匹配数组结构,直接导致解析失败进入onFailure。

  2. 实体类字段错误

    • 字段使用static修饰:Gson基于实例对象赋值,static字段属于类,无法被Gson正确注入值,会导致字段始终为null。
    • 字段类型不匹配:JSON中current/temp/hum的元素是字符串(如"10.79"),但实体类定义为List<Float>,解析时会抛出类型转换异常。
  3. 依赖版本冲突
    OkHttp(3.2.0)与Logging-Interceptor(3.6.0)版本不一致,可能导致请求过程中出现未知异常。

  4. 代码逻辑错误
    即使请求成功,调用ChartResponse.getHum()静态方法获取数据,既不符合实体类设计,也无法正确提取数组中的数据。


分步修复方案

1. 修正Api接口定义

将返回类型改为数组对应的Call<List<DataItem>>,匹配JSON数组结构:

public interface Api {
    @FormUrlEncoded
    @POST("register.php")
    Call<RegisterResponse> register(
            @Field("voltage") String voltage,
            @Field("current") String current,
            @Field("temp") String temp
    );

    @GET("fetch.php")
    Call<List<DataItem>> init(); // 修改为List包裹的DataItem
}

2. 重新定义实体类DataItem

去掉static修饰符,统一字段类型为List<String>(后续再转换为数值):

public class DataItem {
    @SerializedName("voltage")
    @Expose
    private List<String> voltage;

    @SerializedName("current")
    @Expose
    private List<String> current;

    @SerializedName("temp")
    @Expose
    private List<String> temp;

    @SerializedName("hum")
    @Expose
    private List<String> hum;

    // Getter和Setter方法(非静态)
    public List<String> getVoltage() {
        return voltage;
    }

    public void setVoltage(List<String> voltage) {
        this.voltage = voltage;
    }

    public List<String> getCurrent() {
        return current;
    }

    public void setCurrent(List<String> current) {
        this.current = current;
    }

    public List<String> getTemp() {
        return temp;
    }

    public void setTemp(List<String> temp) {
        this.temp = temp;
    }

    public List<String> getHum() {
        return hum;
    }

    public void setHum(List<String> hum) {
        this.hum = hum;
    }
}

3. 修正getData方法逻辑

适配新的接口返回类型,正确提取数据并处理图表渲染:

private void getData() {
    Call<List<DataItem>> call = api.init();

    call.enqueue(new Callback<List<DataItem>>() {
        @Override
        public void onResponse(Call<List<DataItem>> call, Response<List<DataItem>> response) {
            Log.e("CHART_RESPONSE", "请求成功");
            if (response.isSuccessful() && response.body() != null) {
                List<DataItem> dataItems = response.body();
                // 从数组中提取湿度数据(对应JSON的第4个元素)
                List<String> humList = dataItems.get(3).getHum();
                
                BarChart barchart = findViewById(R.id.fragment_verticalbarchart_chart);
                ArrayList<BarEntry> completed = new ArrayList<>();
                
                // 将字符串转换为Float并构建图表数据
                for (int i = 0; i < humList.size(); i++) {
                    float humValue = Float.parseFloat(humList.get(i));
                    BarEntry entry = new BarEntry(i, humValue);
                    completed.add(entry);
                }

                BarDataSet barDataSet = new BarDataSet(completed, "湿度");
                barDataSet.setColor(Color.rgb(0, 155, 0));
                BarData data = new BarData(barDataSet);
                
                barchart.setData(data);
                barchart.invalidate();
            }
        }

        @Override
        public void onFailure(Call<List<DataItem>> call, Throwable t) {
            // 打印详细错误信息,方便排查
            Log.e("CHART_RESPONSE", "请求失败:" + t.getMessage());
            t.printStackTrace();
        }
    });
}

4. 统一依赖版本

修改build.gradle中的依赖,确保OkHttp系列版本一致:

implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.retrofit2:retrofit:2.0.2'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
// 统一OkHttp版本
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0'

额外排查建议

  • 查看Logcat中的错误堆栈信息:onFailure中打印t.printStackTrace()可以看到具体失败原因(如网络连接失败、JSON解析异常等)。
  • 确认设备与服务器处于同一局域网:192.8.1.103是局域网IP,需确保手机/模拟器和服务器在同一网络下。
  • 用浏览器或Postman测试http://192.8.1.103/PHP-API/fetch.php,确认接口返回的JSON格式正确且能正常访问。

内容的提问来源于stack exchange,提问作者鳳凰院凶真

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:25:02