私の ListView は Web サーバーからデータを取得します。
最初に 10 個のアイテムがフェッチされ、後で onScroll でさらに 10 個、というようにフェッチされます。
これは 4 ~ 5 回のスクロールでは正常に機能しますが、後で次の例外が発生します。
java.net.SocketException: Socket closed.
この後:
E/OSNetworkSystem(27034): JNI EX in read
また、 Socket closedの代わりに、次の例外が発生することもあります。
java.io.IOException: Attempted read on closed stream
次に、10 個の新しいアイテムを追加する代わりに、以前に取得した 10 個のアイテムを追加します。これは、例外のために、アダプターで使用される ArrayList の項目を置き換えていないためです。
この例外の原因は何ですか?
編集:
最初の 3 ~ 5 回のスクロールでは問題なく動作し、この例外のために間違ったデータ (前のデータ) が返されます。スクロールを続けると、後で問題なく動作し、後でランダムに例外が返されます。
リスト アイテムを取得するコード:
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;
}
PostData で使用している 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 で、新しいデータ onScroll を取得します。これは 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;
}
では、前のケースでは is(InputStream)とsb(Stringbuilder)がローカル変数ではないためでしょうか?
ありがとうございました