我和app一起调用同一个方法两次,第二次调用方法时它没有用HttResponse执行该行。
以下是一切开始的AsyncTask:
private class FetchSubjectsTask extends AsyncTask<String, Void, List<Subject>> {
private ProgressDialog pd;
@Override
protected List<Subject> doInBackground(String... params) {
List<Subject> subjects = null;
try {
subjects = api.getMySubjects(params[0]);
} catch (Exception e) {
e.printStackTrace();
}
return subjects;
}
@Override
protected void onPostExecute(List<Subject> result) {
printSubjects(result);
if (pd != null) {
pd.dismiss();
}
}
}
然后我通过方法getMySubjects得到主题:
public List<Subject> getMySubjects(String username) {
List<Subject> subjects = new ArrayList<Subject>();
java.lang.reflect.Type arrayListType = new TypeToken<ArrayList<Subject>>() {
}.getType();
String url = BASE_URL_VM + "users/" + username + "/subjects";
HttpClient httpClient = WebServiceUtils.getHttpClient();
try {
System.out.println("inside try");
HttpResponse response = httpClient.execute(new HttpGet(url));
System.out.println("response executed");
HttpEntity entity = response.getEntity();
Reader reader = new InputStreamReader(entity.getContent());
subjects = gson.fromJson(reader, arrayListType);
} catch (Exception e) {
}
System.out.println("Array lenght " +subjects.size());
return subjects;
}
这是第一次HttpResponse执行,我得到了#34;响应被执行&#34;和&#34;阵列长度2&#34;这是用户(用户名)在数据库中拥有的主题数。
问题是在onPostExecute中我调用了printSubjects方法:
private void printSubjects(List<Subject> subjects){
adapter = new SubjectAdapter(this,(ArrayList<Subject>)subjects, (String) getIntent().getExtras().get("username"));
setListAdapter(adapter);
adapter.notifyDataSetChanged();
}
这将调用SubjectAdapter,它在ListView中打印主题:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.subject_detail, null);
viewHolder = new ViewHolder();
viewHolder.tvsubject = (TextView) convertView
.findViewById(R.id.tvsubject);
boolean match = api.checkMySubjects(username, data.get(position).getId());
Button addButton = (Button) convertView.findViewById(R.id.bAdd);
if(match){
addButton.setText("Delete");
}else{
addButton.setText("Add");
}
String content = data.get(position).getName();
viewHolder.tvsubject.setText(content);
}
return convertView;
}
private static class ViewHolder {
TextView tvsubject;
TextView tvauthor;
}
我调用checkMySubjects方法,再次调用getMySubjects进行比较。
public boolean checkMySubjects(String username, String id) {
List<Subject> mySubjects = getMySubjects(username);
boolean match = false;
for (Subject s1 : mySubjects) {
if (s1.getId().equals(id)) {
match = true;
}
}
return match;
}
但是现在方法getMySubjects没有到达&#34;响应被执行&#34;并且数组长度为0.它只显示&#34;内部尝试&#34;。 为什么?我使用相同的URL调用相同的方法但第一次在数组中获得2个主题,第二次我什么也得不到,因为HttResponse没有执行。
谢谢!
答案 0 :(得分:0)
很难说出现了什么,但我想指出我认为这是错的。首先,让我们说明getMySubjects
执行网络操作的事实,现在,第一次调用它时,它是在除了UI线程之外的线程上的AsyncTask
内调用的。这很好
然后你在printSubjects
中拨打onPostExecute
,其中ListView
填充了结果......
private void printSubjects(List<Subject> subjects){
adapter = new SubjectAdapter(this,(ArrayList<Subject>)subjects, (String) getIntent().getExtras().get("username"));
setListAdapter(adapter);
adapter.notifyDataSetChanged();
}
现在,问题在于适配器的getView
实现。更具体地说......
boolean match = api.checkMySubjects(username, data.get(position).getId());
这非常糟糕,因为每次向ListView项目充气时,您都会在UI线程上建立网络连接,因此,如果您有10个项目,您将进行十次网络连接(每次向上滚动和/或在列表中。)
此外,如果您尝试在UI线程上建立网络连接,Android会抱怨FATAL异常。你甚至没有注意到,因为你没有对这个例外做任何事......
try {
System.out.println("inside try");
HttpResponse response = httpClient.execute(new HttpGet(url));
System.out.println("response executed");
HttpEntity entity = response.getEntity();
Reader reader = new InputStreamReader(entity.getContent());
subjects = gson.fromJson(reader, arrayListType);
} catch (Exception e) {
}
catch
块为空,如果您将其打印到LogCat,您将看到详细信息
getView
上而不是为每次迭代建立网络连接,在设置ListView之前急切地将数据加载到内存中同样,有问题的代码行是......
boolean match = api.checkMySubjects(username, data.get(position).getId());
getView
中的