Чтобы в приложении выполнять тяжелые задачи можно вводить отдельный поток и использовать 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() {} 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, имеет доступ к UIonPostExecute
– выполняется после doInBackground (не срабатывает в случае, если AsyncTask был отменен), имеет доступ к UI
При описании класса-наследника AsyncTask мы в угловых скобках указываем три типа данных:
- Тип входных данных. Это данные, которые пойдут на вход AsyncTask.
- Тип промежуточных данных. Данные, которые используются для вывода промежуточных результатов.
- Тип возвращаемых данных. То, что вернет AsyncTask после работы.
Весь класс будет выглядеть примерно так:
public class UpdateTask extends AsyncTask<String, Void, JSONObject> {Context context;public UpdateTask(Context context) {super();this.context = context;}@Overrideprotected void onPreExecute() {super.onPreExecute();}@Overrideprotected 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"));// посылаем запрос методом GETJSONObject json = jParser.makeHttpRequest(url, "GET", params);return json;}@Overrideprotected 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);
Здравствуйте. Отличная статья!
Скажите, пожалуйста, а с чем может быть связано, что при POST запросе выдаётся ошибка
Error parsing data org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject
?
Вот код:
public class POSTUpdateTask extends AsyncTask
{
Context context;
String par_name; String par_value;
String res = «», response;
public POSTUpdateTask(Context context, String par_name, String par_value, String response)
{
super();
this.context = context;
this.par_name = par_name;
this.par_value = par_value;
this.response = response;
}
@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 params = new ArrayList();
params.add(new BasicNameValuePair(par_name, par_value));
params.add(new BasicNameValuePair(«Claim[date_time]», «param_value»));
params.add(new BasicNameValuePair(«Claim[contact_name]», «param_value»));
params.add(new BasicNameValuePair(«Claim[contact_phone]», «param_value»));
params.add(new BasicNameValuePair(«Claim[is_passenger]», «param_value»));
params.add(new BasicNameValuePair(«Claim[adress_from]», «param_value»));
params.add(new BasicNameValuePair(«Claim[is_point]», «param_value»));
params.add(new BasicNameValuePair(«Claim[points][0][address]», «param_value»));
params.add(new BasicNameValuePair(«Claim[points][0][note]», «param_value»));
params.add(new BasicNameValuePair(«Claim[adress_to]», «param_value»));
params.add(new BasicNameValuePair(«Claim[wishes]», «param_value»));
params.add(new BasicNameValuePair(«Claim[purposes]», «param_value»));
params.add(new BasicNameValuePair(«Claim[procuration]», «param_value»));
params.add(new BasicNameValuePair(«Claim[permit]», «param_value»));
// посылаем запрос методом POST
JSONObject json = jParser.makeHttpRequest(url, «POST», params);
return json;
}
@Override
protected void onPostExecute(JSONObject jsonData)
{
// если какой-то фейл, проверяем на null
// фейл может быть по многим причинам: сервер сдох, нет сети на устройстве и т.д.
if (jsonData != null)
{
super.onPostExecute(jsonData);
String res = «»;
try
{
res = jsonData.getString(response);
} catch (JSONException e)
{
e.printStackTrace();
}
Toast.makeText(context, res, Toast.LENGTH_LONG).show();
}
else
{
}
}
}
Вызывается следующим образом: String token = prefs.getString(«token», «»);
new POSTUpdateTask(getActivity(), «access_token», token, «id»)
.execute(«https://id20.ru/api/claim/create/»);
где токен приходит из другого GET запроса.
Спасибо!
Значит приходит на json, а html документ.
а как это исправить?
написать парсер под html