Android: послать GET/POST запрос с помощью AsyncTask

Чтобы в приложении выполнять тяжелые задачи можно вводить отдельный поток и использовать 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 мы в угловых скобках указываем три типа данных:

  1. Тип входных данных. Это данные, которые пойдут на вход AsyncTask.
  2. Тип промежуточных данных. Данные, которые используются для вывода промежуточных результатов.
  3. Тип возвращаемых данных. То, что вернет 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); 
  Категории: Android, java, Коддинг
  • Илья

    Здравствуйте. Отличная статья!
    Скажите, пожалуйста, а с чем может быть связано, что при 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 запроса.
    Спасибо!

    • http://suvitruf.ru Suvitruf

      Значит приходит на json, а html документ.

      • Karo Hovhannisyan

        а как это исправить?

        • Dimasik_eypt

          написать парсер под html