Как сделать блокировку Android HttpRequest - PullRequest
2 голосов
/ 31 января 2012

Вот моя проблема: у меня есть список значений, которые я получаю с сервера.Эти значения заполняют ListView в пользовательском интерфейсе.Я не могу продолжить загрузку просмотра и показывать его пользователю, пока список не будет заполнен.Поскольку Android заставляет меня выполнять HTTP-вызовы в отдельном потоке, мой вопрос заключается в том, как мне создать 1 класс, который выполняет httprequests, а в классе вызова я жду, пока не получу ответ от HttpRequest, и только после этого продолжаю загружать представление?Прямо сейчас у меня есть этот класс, который выполняет запросы:

public class WapConnector extends AsyncTask<String, String, String>{
private static final String TAG = "WapConnector";
private String html = "";
private Handler mHandler;
private String server = "http://....whatever";
private String callUrl = "/api/";
private String params = "login?u=Admin&pw=234234&format=json";
private int _callstate = 1;


@Override
protected String doInBackground(String... uri) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response;
    String responseString = null;
    try {
        String fullUrl = "";
        Log.i(TAG,fullUrl);
        if(params.length() > 0){
            fullUrl = server + callUrl + params + "&alf_ticket=" + Globals.getInstance().getTicket() + "&udid=" + Globals.getInstance().udid() + "&phoneNumber=" + Globals.getInstance().phoneNumber();
        }
        else{
            fullUrl = server + callUrl + "?udid=" + Globals.getInstance().udid() + "&alf_ticket=" + Globals.getInstance().getTicket() + "&phoneNumber=" + Globals.getInstance().phoneNumber();
        }
        Log.i(TAG,fullUrl);
        response = httpclient.execute(new HttpGet(fullUrl));
        StatusLine statusLine = response.getStatusLine();
        if(statusLine.getStatusCode() == HttpStatus.SC_OK){
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.getEntity().writeTo(out);
            out.close();
            responseString = out.toString();
            Log.i(TAG,responseString);
        } else{
            //Closes the connection.
            response.getEntity().getContent().close();
            throw new IOException(statusLine.getReasonPhrase());
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
        //TODO Handle problems..
    } catch (IOException e) {
        //TODO Handle problems..
        e.printStackTrace();
    }
    return responseString;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    Log.i(TAG + "onPostExecute",result);
    activity.getClass().handleResponse();
        //main load
        JSONObject jobj;
        JSONObject jvalue;
        try {
            jobj = new JSONObject(result);
            if(_callstate == 1){
                jvalue = jobj.getJSONObject("data");
                String ticket = jvalue.getString("ticket");
                Log.i("loginwap",ticket);
                Globals.getInstance().setTicket(ticket);
                _callstate = 2;
            }
            else{
                jvalue = jobj.getJSONObject("countries");
                JSONArray countries = jvalue.getJSONArray("countries");

            }
        }
        catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

И вот как я делаю вызовы из родительских классов:

WapConnector wap = new WapConnector();
    wap.setCallUrl("/anyurl/");
    wap.callstate(3);
    wap.setParams("");
    wap.execute("");

Теперь моя проблема заключается в том, что, поскольку запрос выполняется вКогда я вызываю wap.execute (), моя активность продолжает загружаться, но я хочу, чтобы он дождался ответа, проанализировал ответ и только потом продолжил загрузку.

спасибо всем за ответы.!!!

1 Ответ

0 голосов
/ 31 января 2012

Передайте контекст вашему классу из действия, из которого вы его вызываете. Перегрузите onPreExecute (), чтобы показать ProgressDialog, а затем перегрузите onPostExecute (), чтобы скрыть ProgressDialog. Это дает вам блокировку, когда вы загружаете пользователя.

Есть своего рода хакерский способ получить больше контроля. Если вы хотите сохранить AsyncTask как отдельный класс, но разрешить ему обновлять элементы пользовательского интерфейса в другом действии, определите обработчик в этом действии, а затем передайте его в конструктор AsyncTask. Затем вы можете отправить сообщение в методе onPostExecute () вашего AsyncTask обработчику, чтобы сообщить ему об обновлении пользовательского интерфейса. Вам нужно убедиться, что обработчик правильно обрабатывает сообщение, которое AsyncTask отправляет обратно. Может быть немного чище, но это работает и позволит вам повторно использовать asyncTask, который выполняет сетевой вызов между действиями.

...