2012-11-06 67 views
1

我的ListView從Web服務器獲取數據。ListView onScroll導致SocketException

最初將獲取10個項目,之後再捲動10個等等。

也能正常工作4-5滾動,但後來給出了這樣的例外:

java.net.SocketException: Socket closed. 

在此之後:

E/OSNetworkSystem(27034): JNI EX in read 

,有時代替插座關閉,即使是這種例外情況:

java.io.IOException: Attempted read on closed stream 

然後代替添加10 ne w項目,它增加了10個先前提取的項目。這是因爲我沒有替換適配器中使用的ArrayList中的項目,因爲有異常。

什麼原因導致此異常?

編輯:

它工作正常的第一3-5滾動,然後給我,因爲這異常的一些錯誤的數據(以前的數據),如果我繼續滾動,它工作正常後,再次給出了隨機例外。

代碼以獲取列表項:

POSTDATA到我使用POSTDATA從Web服務器

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; 
    } 

ThreadSafeClient獲取數據

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在米在Activity中獲取新數據的活動。這就是所謂的onScroll

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方法在此之後,它工作得很好。

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; 
} 

那麼,是不是因爲是(InputStream的)SB(StringBuilder)對沒有前面的情況局部變量

謝謝

+0

套接字異常一般是不正確的網絡連接花花公子 – Anirudh

+0

如果您的手機的互聯網連接斷開,這個異常被拋出,這不是唯一的原因,這可能是其中一個原因。 – Anirudh

+0

你應該詳細說明你的網絡代碼,它是什麼以及它是如何調用列表滾動的,因爲這是錯誤可能發生的地方。 – Guykun

回答

1

你的方法PostData()不是線程安全的,因爲你正在使用的方法沒有定義兩個對象:

is = entity.getContent(); 
sb = new StringBuilder(); 

這將導致sockect從其他運行線程將被關閉:

is.close(); 

定義它們在本地的方法,它應該解決問題。

問候。

+0

請問您可以檢查最後一次編輯並確認那?謝謝 –

+0

是的。看起來這些局部變量是問題。您開始使用本地對象方法來實現相同的目標,並解決了問題。要構建線程安全代碼,不能在沒有'synchronized()'塊的情況下使用全局對象,原因很簡單,在一個線程設置了對象值之後,它可以被中斷並且另一個線程啓動。該對象中的值將在其他線程中使用/重寫,從而引發該問題。 – Luis

+0

只需再發表一條評論。 'DONUT'之前的SDK和等於或者更新,然後'HONEYCOMB'一次只允許一個'AsyncTask'。如果你想要在所有設備上使用'Thread'類(或其他提供線程的類)的相同行爲(並行)。 – Luis

1

在滾動稱爲每次你的ListView的y座標發生了變化的時候,所以它可能是,你對服務器進行多個連接時,您的列表中滾動,這可能會導致異常。

這可以幫助你: http://benjii.me/2010/08/endless-scrolling-listview-in-android/

+0

但是我在** onScroll **中有條件才能建立連接**只有當最後一個項目到達**並且** ListView沒有被新數據填充** –

相關問題