【问题标题】:Error converting result java.io.IOException: Attempted read on closed stream?转换结果 java.io.IOException 时出错:尝试在关闭的流上读取?
【发布时间】:2015-12-27 08:05:42
【问题描述】:

考虑到下面的代码,当我调用 foo1() 然后 foo2() 时,一切都很好。但是当我将它们一起调用时,我随机得到错误:

  • 错误转换结果 java.io.IOException: 尝试读取已关闭的流。

错误有时与 foo1 有时与 foo2 有关。但是,在每个错误之后,相关方法会停止工作,但会在几秒钟后恢复。如何解决问题?

public class myActivity extends Activity {
//some code including onCreate method
private void foo1() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try{
            while (true){
                JSONParser jsonParser = new JSONParser(); 
                JSONObject jsonObject = jsonParser.getJSONFromUrlByGet(url1);
                myList.add(jsonObject);
                url1 = getNewUrl(url1);                                             
                if(!jsonObject.getJSONObject("pagination").has("next_url"))
                    break;                                                 
            }  catch (Exception exception) {
                exception.printStackTrace();
            }               
        }
    }).start();
}
private void foo2() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try{
            while (true){
                JSONParser jsonParser = new JSONParser(); 
                JSONObject jsonObject = jsonParser.getJSONFromUrlByGet(url2);
                myList.add(jsonObject);
                url2 = getNewUrl(url2);                         
                if(!jsonObject.getJSONObject("pagination").has("next_url"))
                    break;                                                 
            }  catch (Exception exception) {
                exception.printStackTrace();
            }               
        }
    }).start();
}
}

public class JSONParser {
static InputStream is = null;
public JSONObject getJSONFromUrlByGet(String url) {

    try {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);

        HttpResponse httpResponse = httpClient.execute(httpGet);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
    } catch (Exception e) {
    }
    try {
        jObj = new JSONObject(json);
    } catch (JSONException e) {
    }
    return jObj;
}

这是日志:

12-27 11:48:46.076: I/System.out(20738): got foo1 first pack
12-27 11:48:46.201: I/System.out(20738): got foo1 second pack
12-27 11:48:46.771: I/System.out(20738): got foo1 third pack
12-27 11:48:47.386: I/System.out(20738): got foo2 first pack
12-27 11:48:47.391: I/System.out(20738): E/Buffer Error(6888): Error converting result java.io.IOException: Attempted read on closed stream.
12-27 11:48:47.681: I/System.out(20738): got foo2 second pack
12-27 11:48:47.731: I/System.out(20738): got foo1 fourth pack
12-27 11:48:48.651: I/System.out(20738): got foo1 fifth pack
12-27 11:48:48.656: I/System.out(20738): E/Buffer Error(6888): Error converting result java.io.IOException: Attempted read on closed stream.
12-27 11:48:50.826: I/System.out(20738): got foo2 third pack
12-27 11:48:50.836: I/System.out(20738): got foo2 fourth pack
12-27 11:48:50.856: I/System.out(20738): got foo2 fifth pack
12-27 11:48:50.891: I/System.out(20738): got foo2 sixth pack
12-27 11:48:50.891: I/System.out(20738): got foo2 seventh pack
12-27 11:48:52.686: I/System.out(20738): E/Buffer Error(6888): Error converting result java.io.IOException: Attempted read on closed stream.
12-27 11:48:52.696: I/System.out(20738): got foo1 sixth pack

【问题讨论】:

  • 任何时候遇到异常,发布堆栈跟踪

标签: java android


【解决方案1】:

所以问题是您正在使用线程,这些线程会随机执行,因此有时您会在 foo1 和其他时候在 foo2 中出错。

在你的 run() 方法中,你会因为while(true){}而不断循环

假设你的 foo1 开始执行,它进入 while 循环,并调用 getJSONFromUrlByGet(),它依次读取数据直到结束,然后关闭流。见is.close()

但是由于是静态实例,“is”在类的所有实例之间共享。因此,当再次调用 getJSONFromUrlByGet() 时,流已经关闭,因此出现异常。

【讨论】:

  • 我编辑了问题并添加了 InputStream 声明。它是 JSONParser 类中的静态字段。但是我不认为问题来自线程,也不是来自 is.close(),因为每个 while 循环都使用 JSONParser 类的新实例,因此是一个新的输入流。顺便说一句,只要需要,while 循环就会中断。它不是无限的。
  • 可以不加静态试试吗?
  • 去掉静态并将输入流转为字段后,问题就解决了。现在我的应用程序向前迈出了一大步。非常感谢 Rusheel Jain :)
  • 谢谢。将其声明为静态会使您的所有类对象都可以使用同一个实例(静态变量属性)
  • 我建议您编辑您的答案并清楚地解释您在 cmets 中提到的关于尝试不使用静态的内容。这将帮助其他人更快、更清楚地得到答案。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多