Асинхронный HTTP пост андроид - PullRequest
2 голосов
/ 31 марта 2012

Я использую приложение, где мне просто нужно загрузить пару координат для карт Google с сервера MySQL. Я могу сделать это успешно, используя php и обычный httpost, но мое приложение зависает на несколько секунд, когда я это делаю.

Я прочитал, что вам нужно сделать httppost асинхронным, чтобы избежать этого зависания, пока сервер не завершит обработку и не отправит результаты.

Дело в том, что мне нужно, чтобы в результате получился массив json, похожий на обычный httpost.

Например, если бы у меня был этот httppost.

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");

try {
    // Add your data
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
    nameValuePairs.add(new BasicNameValuePair("id", "12345"));
    nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    // Execute HTTP Post Request
    HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
} catch (IOException e) {
    // TODO Auto-generated catch block
}

String result11 = null;
// convert response to string
try {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is11, "iso-8859-1"), 8);
    StringBuilder sb = new StringBuilder();
    sb.append(reader.readLine() + "\n");
    String line = "0";
    while ((line = reader.readLine()) != null) {
        sb.append(line + "\n");
    }
    is11.close();
    result11 = sb.toString();
} catch (Exception e) {
    Log.e("log_tag", "Error converting result " + e.toString());
}

// parsing data
try {
    JSONArray jArray1 = new JSONArray(result11);
} catch (JSONException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Как я могу преобразовать это в асинхронный пост, чтобы я мог избежать замораживания?

Ответы [ 5 ]

5 голосов
/ 31 марта 2012

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

public class FetchTask extends AsyncTask<Void, Void, JSONArray> {
    @Override
    protected JSONArray doInBackground(Void... params) {
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");

            // Add your data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("id", "12345"));
            nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            // Execute HTTP Post Request
            HttpResponse response = httpclient.execute(httppost);

            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            sb.append(reader.readLine() + "\n");
            String line = "0";
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            reader.close();
            String result11 = sb.toString();

            // parsing data
            return new JSONArray(result11);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected void onPostExecute(JSONArray result) {
        if (result != null) {
            // do something
        } else {
            // error occured
        }
    }
}

Вы можете запустить задачу, используя:

new FetchTask().execute();

Дополнительные ресурсы:

3 голосов
/ 15 июня 2012

Я предлагаю использовать библиотеку android-async-http (http://loopj.com/android-async-http/). Это делает Android-асинхронные вызовы http простыми и элегантными.

2 голосов
/ 31 марта 2012

Вместо того, чтобы просто начинать новую тему, лучше использовать полнофункциональную AsyncTask. Это обеспечивает намного больший контроль над вещами.

private class DoPostRequestAsync extends AsyncTask<URL, Void, String> {
     protected String doInBackground(URL url) {
        //Your download code here; work with the url parameter and then return the result
        //which if I remember correctly from your code, is a string.
        //This gets called and runs ON ANOTHER thread
     }

     protected void onPostExecute(String result) {
         //This gets called on the interface (main) thread!
         showDialog("Done! " + result);
     }
 }

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

http://developer.android.com/reference/android/os/AsyncTask.html

1 голос
/ 11 июля 2013

Используйте асинхронную http-библиотеку, например, ion. https://github.com/koush/ion

Все потоки и асинхронный шаблон будут обработаны для вас.

Это тот же код, асинхронный, с использованием Ion. Гораздо проще:

Ion.with(context)
.load("http://www.yoursite.com/script.php")
.setBodyParameter("id", "12345")
.setBodyParameter("stringdata", "AndDev is Cool!")
.asJsonArray()
.setCallback(new FutureCallback<JsonArray> {
  void onCompleted(Exception e, JsonArray result) {
    // do something with the result/exception
  }
});
1 голос
/ 31 марта 2012

Предполагая, что вы хотите сделать это одним нажатием кнопки:

public void onClick(View v) {
  new Thread(new Runnable() {
        public void run() {
            //your code here
        }
    }).start();
}

По сути, вы помещаете интенсивную операцию ввода-вывода в отдельный поток (не в поток вашего интерфейса), чтобы пользовательский интерфейс не зависал.

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