当被调用两次时,代码不会第二次执行HttpResponse

时间:2014-12-15 01:28:21

标签: android http response httpresponse

我和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没有执行。

谢谢!

1 个答案:

答案 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,您将看到详细信息

建议

  1. 不要在UI线程上建立网络连接......你不能
  2. getView上而不是为每次迭代建立网络连接,在设置ListView之前急切地将数据加载到内存中
  3. 同样,有问题的代码行是......

    boolean match = api.checkMySubjects(username, data.get(position).getId());
    
    getView

    中的