我的ListView从Web服务器获取数据。
最初将提取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个以前提取的项目,而不是添加10个新项目。这是因为我没有替换适配器中使用的ArrayList中的项,因为Exception。
导致此异常的原因是什么?
修改
它适用于前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;
}
我的Activity中的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;
}
那么,是因为是(InputStream)而 sb(Stringbuilder)在前一种情况下不是局部变量吗?
谢谢
答案 0 :(得分:1)
每次ListView的y坐标发生变化时都会调用滚动,因此可能是滚动列表时与服务器建立了很多连接,这可能会导致异常。
这可能对您有所帮助: http://benjii.me/2010/08/endless-scrolling-listview-in-android/
答案 1 :(得分:1)
您的方法PostData()
不是线程安全的,因为您使用的方法中没有定义两个对象:
is = entity.getContent();
sb = new StringBuilder();
这导致其他正在运行的线程的sockect被关闭:
is.close();
在方法中本地定义它们,它应该解决问题。
问候。