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

Retrofit XML解析中onResponse未触发,内部类构造报错求排查

我来帮你分析下问题所在,核心原因出在Dealer这个内部类的定义上,另外你没实现onFailure方法也导致你一开始没看到具体错误信息,误以为只是onResponse没被调用。

问题1:非静态内部类无法被SimpleXML转换器实例化

你的Dealer是ApiResponse的非静态内部类,这种类的实例化必须依赖于外部类ApiResponse的实例。但SimpleXML转换器在解析XML时,是直接通过反射创建Dealer对象的,它没有办法先创建ApiResponse实例再去创建Dealer,所以会抛出「无法构造内部类」的异常,这直接导致请求失败,不会进入onResponse方法。

解决方法:把Dealer改成静态内部类

只需要给Dealer类加上static修饰符,让它变成静态内部类,这样它就不再依赖外部类的实例,可以被独立实例化:

@Root(name = "dealers", strict = false)
public class ApiResponse {
    @ElementList(inline = true)
    public List<Dealer> dealerList;

    // 添加static修饰符
    @Root(name = "dealer")
    public static class Dealer {
        @Element(name = "name")
        private String name;
        @Element(name = "google_static_map_url")
        private String staticMapUrl;

        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getStaticMapUrl() { return staticMapUrl; }
        public void setStaticMapUrl(String staticMapUrl) { this.staticMapUrl = staticMapUrl; }
    }
}

问题2:未实现onFailure方法,无法排查错误

你之前的enqueue只实现了onResponse,没有处理失败的情况,所以当请求出错时,你看不到任何错误提示,误以为只是onResponse没触发。一定要实现onFailure方法,它能帮你快速定位请求失败的原因。

完善后的请求代码

给你的请求代码补上onFailure,同时增加一些健壮性判断(比如响应是否成功、body是否为空):

private void getDealerList() {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(API_BASE_URL)
            .client(new OkHttpClient())
            .addConverterFactory(SimpleXmlConverterFactory.create())
            .build();
    MapAPI dealerApiKey = retrofit.create(MapAPI.class);
    Call<ApiResponse> callResponse = dealerApiKey.getList("55082");
    callResponse.enqueue(new Callback<ApiResponse>() {
        @Override
        public void onResponse(Call<ApiResponse> call, Response<ApiResponse> mResponse) {
            // 先判断响应是否成功,body是否非空
            if (mResponse.isSuccessful() && mResponse.body() != null) {
                mDealerList = mResponse.body().dealerList;
                // 注意这里要引用静态内部类:ApiResponse.Dealer
                ArrayList<ApiResponse.Dealer> dealerArrayList = new ArrayList<>(mDealerList);
                adapter = new StoreListAdapter(dealerArrayList, getApplicationContext());
                mRecyclerView.setAdapter(adapter);
            } else {
                // 处理响应不成功的情况,比如打印状态码
                Log.e("DealerRequest", "请求失败,状态码:" + mResponse.code());
            }
        }

        @Override
        public void onFailure(Call<ApiResponse> call, Throwable t) {
            // 打印错误栈信息,方便排查
            t.printStackTrace();
            // 给用户一个友好提示
            Toast.makeText(getApplicationContext(), "获取经销商列表失败:" + t.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

额外注意事项

  1. 检查XML结构与注解匹配:确认你的XML响应结构是<dealers>下直接包含多个<dealer>元素,@ElementList(inline = true)的使用是正确的,它表示列表元素直接内嵌在根元素下,不需要额外的包裹标签。
  2. 确认BaseUrl格式:Retrofit对BaseUrl的格式有要求,如果你的BaseUrl以/结尾,那么@GET的路径不能以/开头(你的@GET("/dealer")如果BaseUrl是https://xxx.com/的话,拼接后是https://xxx.com/dealer,是正确的;如果BaseUrl没有以/结尾,比如https://xxx.com,拼接后会变成https://xxx.comdealer,这就会出错,所以要保证BaseUrl的格式正确)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:43:55