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

Gson反序列化JSON时文档未完全消费及列表为空问题排查

问题排查与解决方案

先帮你拆解一下当前遇到的两个问题,以及对应的解决步骤:

1. 最初「文档未完全消费」错误的根源

你的JSON读取逻辑存在漏洞,原来的循环写法会把null拼接到JSON字符串末尾,导致Gson解析时无法识别完整的JSON结构:

// 错误写法
while (myJSON != null) {
    myJSON = bufferedReaderObject.readLine();
    completeJSONdata += myJSON;
}

当bufferedReaderObject.readLine()返回null(表示读取到末尾)时,你依然把这个null拼进了completeJSONdata,最终JSON字符串会多一个null后缀,自然引发解析错误。

修正后的读取逻辑:用StringBuilder(比字符串拼接更高效),同时在循环条件里直接赋值并判断:

StringBuilder jsonBuilder = new StringBuilder();
String line;
try {
    URL urlObject = new URL("https://api.myjson.com/bins/161kkd");
    HttpURLConnection httpURLConnection = (HttpURLConnection) urlObject.openConnection();
    InputStream inputStreamObject = httpURLConnection.getInputStream();
    BufferedReader bufferedReaderObject = new BufferedReader(new InputStreamReader(inputStreamObject));
    
    while ((line = bufferedReaderObject.readLine()) != null) {
        jsonBuilder.append(line);
    }
    // 记得关闭流和连接,避免资源泄漏
    bufferedReaderObject.close();
    inputStreamObject.close();
    httpURLConnection.disconnect();
} catch (Exception e) {
    e.printStackTrace();
    Log.d(TAG, "doInBackground: 读取JSON失败");
}
String completeJSONdata = jsonBuilder.toString();

2. 列表为空的核心原因

你在主线程里犯了一个典型的异步任务误区:

jsonImportObject.execute();
// 这里新建的是一个空的DeserializedContainer,和AsyncTask返回的完全不是同一个对象!
DeserializedContainer deserializedContainerObject = new DeserializedContainer();
Log.d( TAG, "onCreate: " + deserializedContainerObject);

AsyncTask是异步执行的,execute()调用后立刻返回,此时后台线程还在下载解析JSON,你新建的DeserializedContainer是一个空对象,打印它当然看不到数据。

正确的做法是在OnLoadListener的onSuccess回调里操作返回的有效数据:

JSONimport jsonImportObject = new JSONimport( new JSONimport.OnLoadListener() {
    @Override
    public void onSuccess(DeserializedContainer container) {
        // 在这里打印或使用解析后的数据
        List<DeserializedVariables> movieList = container.getDeserializedContainerList();
        Log.d(TAG, "解析到的电影数量:" + movieList.size());
        for (DeserializedVariables movie : movieList) {
            Log.d(TAG, "电影:" + movie.movieName + " - " + movie.movieYear + "年 - 评分:" + movie.movieRating);
        }
    }
} );
jsonImportObject.execute();

另外,为了让DeserializedVariables能正常打印内容,建议给它重写toString()方法:

public class DeserializedVariables {
    @SerializedName( "movieName" )
    private String movieName;
    @SerializedName( "movieYear" )
    private int movieYear;
    @SerializedName( "movieRating" )
    private double movieRating;

    // 重写toString,方便打印查看
    @Override
    public String toString() {
        return "DeserializedVariables{" +
                "movieName='" + movieName + '\'' +
                ", movieYear=" + movieYear +
                ", movieRating=" + movieRating +
                '}';
    }
}

额外优化建议

  • 尽量避免使用已被废弃的AsyncTask,可以改用Coroutines、OkHttp+Retrofit等现代网络请求方案,代码更简洁且更稳定。
  • 网络请求记得添加权限:在AndroidManifest.xml里加入<uses-permission android:name="android.permission.INTERNET"/>(如果是Android 9及以上,还要注意清除明文网络限制,或者在AndroidManifest.xml的application标签里添加android:usesCleartextTraffic="true")。

内容的提问来源于stack exchange,提问作者Joakim Sjöstedt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:44:01