首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ListView onScroll引起SocketException

ListView onScroll引起SocketException
EN

Stack Overflow用户
提问于 2012-11-06 11:08:25
回答 2查看 255关注 0票数 1

我的ListView从web服务器获取数据。

最初将获取10个项目,然后再获取onScroll 10个,依此类推。

这对于4-5卷轴很好,但是稍后给出了这个例外:

代码语言:javascript
复制
java.net.SocketException: Socket closed.

在此之后:

代码语言:javascript
复制
E/OSNetworkSystem(27034): JNI EX in read

有时,与套接字关闭的不同,甚至会出现以下异常:

代码语言:javascript
复制
java.io.IOException: Attempted read on closed stream

然后,它没有添加10个新项,而是添加了10个先前获取的项。这是因为我不会替换适配器中使用的ArrayList中的项,因为异常。

是什么导致了这一异常?

编辑:

它对前3-5滚动很好,然后给我一些错误的数据(以前的数据),因为这个异常,如果我继续滚动,它工作良好,然后再给出异常,随机。

获取列表项的代码:

从web服务器获取数据的postData

代码语言:javascript
复制
public static String PostData(String url, String sa[][]) {

        DefaultHttpClient client = getThreadSafeClient();
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        int n = sa.length;
        for (int i = 0; i < n; i++) {
            nameValuePairs.add(new BasicNameValuePair(sa[i][0], sa[i][1]));
            Log.d(sa[i][0], "" + sa[i][1]);
        }
        HttpPost httppost;
        try {
            httppost = new HttpPost(baseUrl + url);
        } catch (Exception e) {
        }
        try {
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        } catch (UnsupportedEncodingException e) {
        }
        HttpResponse response = null;
        try {
            response = client.execute(httppost);
        } catch (ClientProtocolException e) {
        } catch (IOException e) {
        } catch (Exception e) {
        }
        HttpEntity entity = response.getEntity();
        try {
            is = entity.getContent();
        } catch (IllegalStateException e) {
        } catch (IOException e) {
        }
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            sb = new StringBuilder();
            sb.append(reader.readLine());
            String line = "0";
            while ((line = reader.readLine()) != null) {
                sb.append("\n" + line);
            }
            is.close();
            result = sb.toString();
        } catch (Exception e) {
        }
        return result;
    }

我在PostData中使用的PostData

代码语言:javascript
复制
    public static DefaultHttpClient getThreadSafeClient() {

    DefaultHttpClient client = new DefaultHttpClient();
    ClientConnectionManager mgr = client.getConnectionManager();
    HttpParams params = client.getParams();
    client = new DefaultHttpClient(new ThreadSafeClientConnManager(params,
            mgr.getSchemeRegistry()), params);
    return client;
}

AsyncTask在我的活动中获取新的数据onScroll。这在onScroll中被调用

代码语言:javascript
复制
AsyncTask{

ArrayList<item> itemList = new Arraylist<item>();
doInBackground(){

    String response = PostData(url, sa);
    //sa has namevaluepairs as a 2-dimensional array
    JSONArray JArray = new JSONArray(response);
    for(int i = 0; i < jArray.length; i++){

        itemList.add(convertToItem(JArrya.getJSONObject("items")));
    }
}
onPostExecute(){

    for(int i = 0; i < itemList.size(); i++){
        mListAdapter.add(itemList.get(i));
    }
    mListAdapter.notifyDataSetChanged();
}
}

这是一段很长的代码,所以只粘贴重要的行。

任何帮助都很感激。

编辑:

在将PostData方法更改为此之后,它工作得很好。

代码语言:javascript
复制
public static String PostData(String url, String sa[][]) {

    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
    int n = sa.length;
    for (int i = 0; i < n; i++) {
        nameValuePairs.add(new BasicNameValuePair(sa[i][0], sa[i][1]));
    }
    HttpPost httppost;
    httppost = new HttpPost(baseUrl + url);
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    HttpResponse response = null;
    response = client.execute(httppost);
    HttpEntity entity = response.getEntity();
    String res = EntityUtils.toString(entity);
    return res;
}

那么,是不是因为在前面的例子中,is(InputStream)sb(Stringbuilder)不是局部变量

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-24 15:20:38

您的方法PostData()不是线程安全的,因为您使用的是未在该方法中定义的两个对象:

代码语言:javascript
复制
is = entity.getContent();
sb = new StringBuilder();

这将导致来自其他正在运行的线程的套接字通过以下方式关闭:

代码语言:javascript
复制
is.close();

将两者在本地定义为该方法,并应解决此问题。

致以问候。

票数 1
EN

Stack Overflow用户

发布于 2012-11-22 14:39:44

每当ListView的y坐标发生变化时,都会调用滚动页,因此,当列表被滚动时,您可能会与服务器建立许多连接,这可能会导致异常。

这可能对你有帮助:http://benjii.me/2010/08/endless-scrolling-listview-in-android/

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13249704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档