Как использовать отдельный поток для выполнения http-запросов - PullRequest
22 голосов
/ 02 августа 2010

У меня есть приложение, которое выполняет HTTP-запросы (в частности, вызывает FogBugz API), когда пользователь нажимает определенные кнопки. Прямо сейчас я просто создаю службу при запуске приложения, а затем вызываю различные методы в этой службе для выполнения запросов. Однако, когда я делаю это, в потоке пользовательского интерфейса происходит обычное зависание. Я посмотрел на AsyncTask, но не уверен, что он будет делать то, что я хочу достичь. Поскольку мне нужно мгновенно проанализировать XML, возвращаемый HTTP-запросом, мне нужен процесс, который может вернуть эти данные в поток пользовательского интерфейса. Сможет ли ASyncTask добиться этого или есть какой-то другой способ?

    public static InputStream makeRequest(String httpRequest)
    {
        In a separate thread, run HTTP Request, get back and process, return inputstream
    }

Этот метод вызывается несколькими другими для выполнения HttpRequests. Как только входной поток возвращается, другие методы анализируют определенную информацию.

Ответы [ 2 ]

69 голосов
/ 02 августа 2010

Самый простой способ сделать это - сделать что-то вроде

//Body of your click handler
Thread thread = new Thread(new Runnable(){
  @Override
  public void run(){
    //code to do the HTTP request
  }
});
thread.start();

, что приведет к выполнению кода внутри метода run() в новом потоке выполнения.Вы можете посмотреть асинхронную задачу, если хотите, хотя я лично никогда не использовал ее.Это быстрый и простой способ добиться цели.

Что касается передачи информации обратно, я бы использовал объект-обработчик , который эффективно позволяет вам настроить очередь сообщений для данногопоток и передавать ему сообщения, которые вызывают выполнение конкретного кода.Причина, по которой вам нужно это сделать, заключается в том, что Android не позволяет ни одному потоку, кроме потока пользовательского интерфейса, обновлять фактический пользовательский интерфейс.

Отвечает ли это на ваш вопрос?Я знаю, что мой первый проход не полностью решил все ваши проблемы.

Редактировать По сути, вы определяете объект-обработчик в вашем Activity как

private Handler handler_ = new Handler(){
    @Override
    public void handleMessage(Message msg){

    }

};

Вы также создаете статические int константы, которые помогают указывать обработчику, что делать.Вы в основном используете их, чтобы разрешить нескольким различным типам сообщений передаваться одному экземпляру обработчика.Если будет только одно сообщение, которое будет передано обратно, вам не нужно об этом беспокоиться.

Например

private static final int UPDATE_UI = 1;

Чтобы отправить сообщение обработчику, выcall

handler_.sendMessage(Message.obtain(handler_, UPDATE_UI, inputStreamInstance));

Из обработчика:

private Handler handler_ = new Handler(){
    @Override
public void handleMessage(Message msg){
    switch(msg.what){
            case UPDATE_UI:
            InputStream is = (InputStream)msg.obj;
            //do what you need to with the InputStream
            break;
        }
    }

};

В качестве альтернативы, когда inputStreamInstance добавляется к объекту Message, вы можете передать любой понравившийся объект, так что если вы хотите проанализироватьэто в какой-то контейнерный объект или что-то в этом роде, вы также можете сделать это.Просто приведите его обратно к этому объекту из обработчика.

5 голосов
/ 21 июня 2012

Попробуйте использовать AsyncTask.Перейти к этому Ссылка для получения дополнительной информации:

private class SyncIncoData extends AsyncTask<String, String, String> {
    ProgressBar pb;
    ProgressBar pbar;

    @Override
    protected String doInBackground(String... urls) {
        for (int i = 0; i <= 100; i++) {
            publishProgress(i);
        }
        return null;
    }

    @Override
    protected void onPreExecute() {

        super.onPreExecute();

        pb = (ProgressBar) findViewById(R.id.progressBarsync4);
        pb.setVisibility(View.VISIBLE);

    }

    @Override
    protected void onPostExecute(String result) {

        pb = (ProgressBar) findViewById(R.id.progressBarsync4);
        pb.setVisibility(View.INVISIBLE);

    }

    @Override
    protected void onProgressUpdate(String... values) {
        pbar = (ProgressBar) findViewById(R.id.progressBarpbar);
        pbar.setProgress(Integer.parseInt(values[0]));
        super.onProgressUpdate(values);
    }
}

Написать программу для http запроса внутри doinbackgroud()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...