Чтобы в приложении выполнять тяжелые задачи можно вводить отдельный поток и использовать Handler для обратной связи и обновления экрана. Для решения подобных задач сделали отдельный класс – AsyncTask. Т.е. его цель – это выполнение тяжелых задач и передача в UI-поток результатов работы. При этом нам не надо задумываться о создании Handler и нового потока. Для отправки запросов вроде как тоже рекомендуется использовать AsyncTask.
JSONParser
Данные с сервера частенько отправляют в формате JSON. Поэтому, можно воспользоваться классом для отправки запросов в json формате. Код нашёл на просторах http://stackoverflow.com
public class JSONParser { static InputStream is = null; static JSONObject jObj = null; static String json = ""; // конструктор public JSONParser() { } /** * Получить ответ по ссылке в формате json * @param url запрашиваемая страница * @param method GET or POST * @param params параметры, которые необходимо передать * @return */ public JSONObject makeHttpRequest(String url, String method, List<NameValuePair> params) { // создаём HTTP запрос try { if(method == "POST"){ DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new UrlEncodedFormEntity(params)); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); }else if(method == "GET"){ DefaultHttpClient httpClient = new DefaultHttpClient(); String paramString = URLEncodedUtils.format(params, "utf-8"); url += "?" + paramString; HttpGet httpGet = new HttpGet(url); HttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); json = sb.toString(); } catch (Exception e) { Log.e("Buffer Error", "Error converting result " + e.toString()); } // пробуем распарсит JSON объект try { jObj = new JSONObject(json); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } return jObj; } }
AsyncTask
Чтобы работать с AsyncTask
, необходимо создать класс-наследник и в нём переопределить необходимые методы:
doInBackground
– будет выполнен в новом потоке, здесь решаем все свои задачи
onPreExecute
– выполняется перед doInBackground, имеет доступ к UI
onPostExecute
– выполняется после doInBackground (не срабатывает в случае, если AsyncTask был отменен), имеет доступ к UI
При описании класса-наследника AsyncTask мы в угловых скобках указываем три типа данных:
- Тип входных данных. Это данные, которые пойдут на вход AsyncTask.
- Тип промежуточных данных. Данные, которые используются для вывода промежуточных результатов.
- Тип возвращаемых данных. То, что вернет AsyncTask после работы.
Весь класс будет выглядеть примерно так:
public class UpdateTask extends AsyncTask<String, Void, JSONObject> { Context context; public UpdateTask(Context context) { super(); this.context = context; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected JSONObject doInBackground(String... urls) { return loadJSON(urls[0]); } public JSONObject loadJSON(String url) { JSONParser jParser = new JSONParser(); // здесь параметры необходимые в запрос добавляем List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("my_param", "param_value")); // посылаем запрос методом GET JSONObject json = jParser.makeHttpRequest(url, "GET", params); return json; } @Override protected void onPostExecute(JSONObject jsonData) { // если какой-то фейл, проверяем на null // фейл может быть по многим причинам: сервер сдох, нет сети на устройстве и т.д. if (jsonData != null) { super.onPostExecute(jsonData); String res = ""; try { // прочитать параметр, который отправил сервер; // здесь вместо "result" подставляйте то, что вам надо res = jsonData.getString("result"); // что-то делаем, к примеру вызываем метод главного Activity на обновление GUI ((MainActivity) context).updateGUI(res); } catch (JSONException e) { e.printStackTrace(); } } else { ((MainActivity) context).updateGUI(res); } } }
Ну и само использование:
new UpdateTask(this).execute("http://страница_необходимая");
На сервере для нашего случая в php у нас к примеру (параметр «result» мы и пытаемся на клиенте получить):
$res['result'] = 'cool'; $json = json_encode($res);