Java 使用gson解析JSON-解析时套接字关闭

Java 使用gson解析JSON-解析时套接字关闭,java,android,json,gson,Java,Android,Json,Gson,我尝试使用gson解析JSON,如下代码段所示: { "cod":"200", "message":0, "cnt":40, "list":[ {"dt":1584565200,"main":{"temp":284.22,"feels_like":279.95,"temp_min":282.33,"temp_max":284.22,"pressure":1021,"sea_level":1021,"grnd_level":1011,"humidity":81,"temp_kf":1.89},"w

我尝试使用gson解析JSON,如下代码段所示:

{
"cod":"200",
"message":0,
"cnt":40,
"list":[
{"dt":1584565200,"main":{"temp":284.22,"feels_like":279.95,"temp_min":282.33,"temp_max":284.22,"pressure":1021,"sea_level":1021,"grnd_level":1011,"humidity":81,"temp_kf":1.89},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":100},"wind":{"speed":5.42,"deg":275},"sys":{"pod":"n"},"dt_txt":"2020-03-18 21:00:00"},
{"dt":1584576000,"main":{"temp":282.97,"feels_like":279.59,"temp_min":281.55,"temp_max":282.97,"pressure":1021,"sea_level":1021,"grnd_level":1011,"humidity":88,"temp_kf":1.42},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":4.14,"deg":273},"rain":{"3h":0.44},"sys":{"pod":"n"},"dt_txt":"2020-03-19 00:00:00"},
{"dt":1584586800,"main":{"temp":281.44,"feels_like":277.55,"temp_min":280.5,"temp_max":281.44,"pressure":1020,"sea_level":1020,"grnd_level":1010,"humidity":87,"temp_kf":0.94},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":4.33,"deg":286},"rain":{"3h":0.81},"sys":{"pod":"n"},"dt_txt":"2020-03-19 03:00:00"},
{"dt":1584597600,"main":{"temp":279.82,"feels_like":276.13,"temp_min":279.35,"temp_max":279.82,"pressure":1021,"sea_level":1021,"grnd_level":1011,"humidity":89,"temp_kf":0.47},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":100},"wind":{"speed":3.66,"deg":311},"rain":{"3h":0.56},"sys":{"pod":"d"},"dt_txt":"2020-03-19 06:00:00"}]
实际上它要长得多,大约有15000个字符。 我只需要temp、dts、雨或雪降水,所以我创建了以下类:

ForecastParams.java

import java.util.List;

public class ForecastParams {
    public List<_List> list;
}
Main.java

public class Main {
    public double temp;
    public double feels_like;
    public double temp_min;
    public double temp_max;
    public int pressure;
    public int humidity;
}
Rain.java

public class Rain {
    @SerializedName("3h")
    public double rainPrep;
}
Snow.java

public class Snow {
    @SerializedName("3h")
    public double snowPrep;
}
我使用AsyncTask从服务器获取json,然后解析它(在主活动中):

启动应用程序时,我会收到以下堆栈跟踪:

W/System.err: android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
        at java.net.SocketInputStream.read(SocketInputStream.java:175)
        at java.net.SocketInputStream.read(SocketInputStream.java:144)
        at com.android.okhttp.okio.Okio$2.read(Okio.java:136)
W/System.err:     at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
        at com.android.okhttp.okio.RealBufferedSource.read(RealBufferedSource.java:50)
        at com.android.okhttp.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:393)
        at com.android.okhttp.okio.RealBufferedSource$1.read(RealBufferedSource.java:371)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:351)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:180)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1291)
        at com.google.gson.stream.JsonReader.skipQuotedValue(JsonReader.java:1119)
        at com.google.gson.stream.JsonReader.skipValue(JsonReader.java:1253)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
        at com.google.gson.Gson.fromJson(Gson.java:932)
        at com.google.gson.Gson.fromJson(Gson.java:870)
        at com.pklos.myweather.MainActivity$getForecastData.onPostExecute(MainActivity.java:243)
        at com.pklos.myweather.MainActivity$getForecastData.onPostExecute(MainActivity.java:202)
        at android.os.AsyncTask.finish(AsyncTask.java:695)
        at android.os.AsyncTask.access$600(AsyncTask.java:180)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
当我像这样打开StrictMode时(在onCreate方法中):

我得到如下堆栈跟踪(套接字关闭):


我的问题是为什么插座是关闭的?我被一个应用程序已经从服务器下载了json的事实弄糊涂了。以同样的方式,我解析了另一个JSON(大约500个字符),它工作正常。信息量在这里至关重要吗?或者,处理JSON信息的类的编写方式不正确?有没有其他方法来处理这个问题?

我有两个提示。我可能会尝试重写
doInBackground
,使其返回的是解析的
ForecastParams
,而不是Reader,因此您必须解析网络线程中的数据。第二个注意事项是,
AsyncTask
最终被标记为不推荐使用,它的使用被视为一种不好的做法。@MichalHarakal我如您所述重写了
doInBackground
,但没有任何更改,仍然
套接字关闭
。有没有什么方便的方法不将整个JSON加载到内存或使其可流化?我不确定,但为了避免反序列化中的错误,您可以尝试将整个数据作为字符串下载,稍后再进行解析。我知道,这不是最好的,它只是会告诉你下载和解析是正确的。我在这个线程中找到了从链接(readUrl方法)读取JSON文件的合适代码:。我的解析器工作正常,但至少不是以我预测的正确方式工作的——dts和TEMP解析得很好,但我有一个沉淀的问题,在JSON中没有提到它。我尝试过处理空值,比如'Double rain=(weather.rain.rainPrep==null)?0.0:天气、雨水、雨水准备;'但它不起作用。你知道怎么处理吗?我有两个提示。我可能会尝试重写
doInBackground
,使其返回的是解析的
ForecastParams
,而不是Reader,因此您必须解析网络线程中的数据。第二个注意事项是,
AsyncTask
最终被标记为不推荐使用,它的使用被视为一种不好的做法。@MichalHarakal我如您所述重写了
doInBackground
,但没有任何更改,仍然
套接字关闭
。有没有什么方便的方法不将整个JSON加载到内存或使其可流化?我不确定,但为了避免反序列化中的错误,您可以尝试将整个数据作为字符串下载,稍后再进行解析。我知道,这不是最好的,它只是会告诉你下载和解析是正确的。我在这个线程中找到了从链接(readUrl方法)读取JSON文件的合适代码:。我的解析器工作正常,但至少不是以我预测的正确方式工作的——dts和TEMP解析得很好,但我有一个沉淀的问题,在JSON中没有提到它。我尝试过处理空值,比如'Double rain=(weather.rain.rainPrep==null)?0.0:天气、雨水、雨水准备;'但它不起作用。你知道怎么处理吗?
private class getForecastData extends AsyncTask<String, Void, Reader>{
        private Reader json;

        @Override
        protected Reader doInBackground(String... urls){
            try{
                json = RestAPIService.getStream(urls[0]);
            }catch (Exception e){
                e.printStackTrace();
            }

            return json;
        }

        @Override
        protected void onPostExecute(Reader json){
            try{
                Gson gson = new Gson();
                ForecastParams response = gson.fromJson(json, ForecastParams.class);
                List<_List> forecastList = response.list;
                double temp = 0;
                List<Long> dayTime = new ArrayList<>();
                List<Double> temps = new ArrayList<>();
                List<Double> rainPrep = new ArrayList<>();
                List<Double> snowPrep = new ArrayList<>();

                for (_List weather : forecastList){
                    dayTime.add(weather.dt);
                    temps.add(weather.main.temp);
                    rainPrep.add(weather.rain.rainPrep);
                    snowPrep.add(weather.snow.snowPrep);
                }

                setDtList(dayTime);
                setTempsList(temps);                
                setRainPrepList(rainPrep);
                setSnowPrepList(snowPrep);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
static Reader getStream(String url) throws IOException {
    URL obj = new URL(url);
    HttpURLConnection connection = (HttpURLConnection)obj.openConnection();
    InputStream resBody;
    connection.setRequestMethod("GET");
    int responseCode = connection.getResponseCode();

    if (responseCode == HttpURLConnection.HTTP_OK) {
       resBody = connection.getInputStream();
    } else
        return null;

    connection.disconnect();

    Reader resBodyReader = new InputStreamReader(resBody, "UTF-8");

    return resBodyReader;
}
W/System.err: android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
        at java.net.SocketInputStream.read(SocketInputStream.java:175)
        at java.net.SocketInputStream.read(SocketInputStream.java:144)
        at com.android.okhttp.okio.Okio$2.read(Okio.java:136)
W/System.err:     at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
        at com.android.okhttp.okio.RealBufferedSource.read(RealBufferedSource.java:50)
        at com.android.okhttp.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:393)
        at com.android.okhttp.okio.RealBufferedSource$1.read(RealBufferedSource.java:371)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:351)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:180)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1291)
        at com.google.gson.stream.JsonReader.skipQuotedValue(JsonReader.java:1119)
        at com.google.gson.stream.JsonReader.skipValue(JsonReader.java:1253)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
        at com.google.gson.Gson.fromJson(Gson.java:932)
        at com.google.gson.Gson.fromJson(Gson.java:870)
        at com.pklos.myweather.MainActivity$getForecastData.onPostExecute(MainActivity.java:243)
        at com.pklos.myweather.MainActivity$getForecastData.onPostExecute(MainActivity.java:202)
        at android.os.AsyncTask.finish(AsyncTask.java:695)
        at android.os.AsyncTask.access$600(AsyncTask.java:180)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); 
W/System.err: com.google.gson.JsonSyntaxException: java.net.SocketException: Socket closed
        at com.google.gson.Gson.fromJson(Gson.java:947)
        at com.google.gson.Gson.fromJson(Gson.java:870)
        at com.pklos.myweather.MainActivity$getForecastData.onPostExecute(MainActivity.java:243)
        at com.pklos.myweather.MainActivity$getForecastData.onPostExecute(MainActivity.java:202)
        at android.os.AsyncTask.finish(AsyncTask.java:695)
        at android.os.AsyncTask.access$600(AsyncTask.java:180)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
        at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err:     at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
    Caused by: java.net.SocketException: Socket closed
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:119)
        at java.net.SocketInputStream.read(SocketInputStream.java:176)
W/System.err:     at java.net.SocketInputStream.read(SocketInputStream.java:144)
        at com.android.okhttp.okio.Okio$2.read(Okio.java:136)
        at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
        at com.android.okhttp.okio.RealBufferedSource.read(RealBufferedSource.java:50)
        at com.android.okhttp.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:393)
        at com.android.okhttp.okio.RealBufferedSource$1.read(RealBufferedSource.java:371)
W/System.err:     at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:351)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:180)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1291)
        at com.google.gson.stream.JsonReader.nextQuotedValue(JsonReader.java:1031)
        at com.google.gson.stream.JsonReader.nextName(JsonReader.java:788)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:217)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
        at com.google.gson.Gson.fromJson(Gson.java:932)
        ... 12 more