【问题标题】:App crashes AsyncTask downloading JSON from remote server应用程序崩溃 AsyncTask 从远程服务器下载 JSON
【发布时间】:2019-04-05 06:40:50
【问题描述】:

我正在开发一个 Android 应用程序并从远程服务器下载 JSON 字符串。 这是我的功能:

private void getAddressesFromDB() {

    spinner.setVisibility(View.VISIBLE);


    calendarios.clear();

   this is line 218->  AsyncTask<Integer, Void, Void> asyncTask = new AsyncTask<Integer, Void, Void>() {
        @Override
        protected Void doInBackground(Integer... addressesIds) {


            OkHttpClient client = new OkHttpClient();


            Request request = new Request.Builder().addHeader("Cache-Control", "no-cache")
                    .url("https://...cargar_calendario.php?colegio="+colegio)
                    .build();

            try {
                okhttp3.Response response = client.newCall(request).execute();
                Log.d("HOLA ADDRESSES", "ESTOY EN START:CREATE colegio=>"+response.body().string() );

                JSONArray array = new JSONArray(response.body().string());<- this is line 237



                for (int i = 0; i < array.length(); i++) {

                    JSONObject object = array.getJSONObject(i);

                    Calendario calendario = new Calendario(object.getString("holidayDescr"),object.getString("dt"), object.getString("lectivo"));


                }


            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {


            spinner.setVisibility(View.GONE);
        }
    };

    asyncTask.execute();
}

这是接收到的 JSON 字符串:

[{"dt":"2018-01-01","holidayDescr":"Lectivo","lectivo":"1"},{"dt":"2018-01-02","holidayDescr":"Lectivo","lectivo":"1"},{"dt":"2018-01-03","holidayDescr":"Lectivo","lectivo":"1"},{"dt":"2018-01-04","holidayDescr":"Lectivo","lectivo":"1"},{"dt":"2018-01-05","holidayDescr":"Lectivo","lectivo":"1"},{"dt":"2018-01-06","holidayDescr":"","lectivo":"0"},{"dt":"2018-01-07","holidayDescr":"","lectivo":"0"},{"dt":"2018-01-08","holidayDescr":"Lectivo","lectivo":"1"},{"dt":"2018-01-09","holidayDescr":"Lectivo","lectivo":"1"},{"dt":"2018-01-10","holidayDescr":"Lectivo","lectivo":"1"}]

这是异常消息:

    --------- beginning of crash
2018-11-01 03:31:21.028 32425-592/com.juarezserver.pupilam E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
    Process: com.juarezserver.pupilam, PID: 32425
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:325)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
        at java.util.concurrent.FutureTask.run(FutureTask.java:242)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
     Caused by: java.lang.IllegalStateException: closed
        at okio.RealBufferedSource.rangeEquals(RealBufferedSource.java:408)
        at okio.RealBufferedSource.rangeEquals(RealBufferedSource.java:402)
        at okhttp3.internal.Util.bomAwareCharset(Util.java:432)
        at okhttp3.ResponseBody.string(ResponseBody.java:174)
        at com.juarezserver.pupilam.fragment.CalendarioFragment$1.doInBackground(CalendarioFragment.java:237)
        at com.juarezserver.pupilam.fragment.CalendarioFragment$1.doInBackground(CalendarioFragment.java:218)
        at android.os.AsyncTask$2.call(AsyncTask.java:305)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
        at java.lang.Thread.run(Thread.java:761) 

我的代码有什么问题?

【问题讨论】:

  • 您确定您在代码中标记的那些行是正确的吗?您可以确保您的构建和堆栈跟踪都是最新的。堆栈跟踪似乎表明异常发生在response.body().string() 调用之一;我会说第二个。我猜,异常消息是说您只能调用一次string(),可能吗?存储第一次调用的结果,并在两个地方都使用它,而不是 response.body().string() 两次。
  • @MikeM.,标记的行是正确的。
  • 请尝试我的建议。
  • 是的,你去。第 237 行是第二个 response.body().string() 调用。
  • @MikeM.,对不起,第 237 行是另一个代码行,在我的问题中已更改

标签: android json okhttp


【解决方案1】:

使用这个

   try {
                okhttp3.Response response = client.newCall(request).execute();
                Log.d("HOLA ADDRESSES", "ESTOY EN START:CREATE colegio=>"+response.body().string() );

                client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                e.printStackTrace();
                 }

    @Override
    public void onResponse(Call call, final Response response) throws IOException {
        if (!response.isSuccessful()) {
            throw new IOException("Unexpected code " + response);
        } else {
                  JSONArray array = new JSONArray(response);<- this is line 237



                for (int i = 0; i < array.length(); i++) {

                    JSONObject object = array.getJSONObject(i);

                    Calendario calendario = new Calendario(object.getString("holidayDescr"),object.getString("dt"), object.getString("lectivo"));


                }
        }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

【讨论】:

    【解决方案2】:

    您的日志语句在字符串方法的末尾关闭 RealBufferedSource,您可以像这样更改日志语句。

    Log.d("HOLA ADDRESSES", "ESTOY EN START:CREATE colegio=>"+response.body());
    

    理想的解决方案是为您的响应数据创建模型类并进行更改以从 api 调用返回数据数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      相关资源
      最近更新 更多