Java: uma solicitação de WebService incorporada em uma AsyncTask
. Olá, como um jovem desenvolvedor Android, eu estava procurando uma maneira de obter uma resposta JSON de um servidor. Comecei a olhar para o AsyncTask, mas não me sinto confortável em codificar um AsyncTask para cada vez que precisava solicitar um WebService.
Então comecei a codificar uma classe (estende o AsyncTask) que consulta uma URL (POST ou GET) e fornece um retorno de chamada contendo a resposta do servidor. Eu queria ter algum feedback, é realmente útil, e não uma sobreposição inútil de uma AsyncTask porque eu perdi de entender algo no começo. Quanto mais eu codifico, mais duvido.
Agradecemos antecipadamente por seus comentários.
Aqui está o código que eu uso para consultar um servidor com minha classe:
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("address", "sidney");
parameters.put("sensor", "false");
WebServiceAsyncTask asyncWS = new WebServiceAsyncTask(MainActivity.this);
asyncWS.setParameters(parameters);
asyncWS.execute(
"http://maps.googleapis.com/maps/api/geocode/json",
WebServiceAsyncTask.GET,
new WebServiceAsyncTaskCallback() {
@Override
void callbackMethod(String result) {
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
}
}
);
Aqui está o código do meu WebServiceAsyncTask:
import android.app.ProgressDialog;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Anthony Raymond
*/
public class WebServiceAsyncTask extends AsyncTask<Object, String, String> {
public static final String GET = "GET";
public static final String POST = "POST";
private static final String PROGRESS_TEXT_PREPARING = "Preparing request";
private static final String PROGRESS_PERCENT_PREPARING = "25";
private static final String PROGRESS_TEXT_CONNECTION_SERVER = "Connecting to the server";
private static final String PROGRESS_PERCENT_CONNECTION_SERVER = "50";
private static final String PROGRESS_TEXT_PARSING = "Parsing received data";
private static final String PROGRESS_PERCENT_PARSING = "75";
private static final String PROGRESS_TEXT_END = "Process ended";
private static final String PROGRESS_PERCENT_END = "100";
private Context context;
private HashMap<String, String> mData = new HashMap<String, String>();
private ProgressDialog progressDialog;
private WebServiceAsyncTaskCallback callbackClass;
/**
* If a Context is passed, a ProgressDialog will be displayed
* NEED TO PASS Context LIKE THIS :
* MyActivity.this
* DO NOT USE getApplicationContext()
* @param applicationContext
*/
public WebServiceAsyncTask(Context applicationContext)
{
this.context = applicationContext;
}
/**
* Create a WebServiceAsyncTask.
* Usage : add request parameter by passing an HashMap<String, String> with the setParameter Method, then call
* .execute(String url, WebServiceAsyncTask constant (GET or SET), WebServiceAsyncTaskCallback callback)
* exemple :
* HashMap<String, String> parameters = new HashMap<String, String>();
* parameters.put("address", "Sidney");
* parameters.put("sensor", "false");
* WebServiceAsyncTask asyncWS = new WebServiceAsyncTask(MainActivity.this);
* asyncWS.setParameters(parameters);
* asyncWS.execute(
* "http://maps.googleapis.com/maps/api/geocode/json",
* WebServiceAsyncTask.GET,
* new WebServiceAsyncTaskCallback() {
* @Override
* void callbackMethod(String result) {
* Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
* }
* }
* );
*/
public WebServiceAsyncTask()
{
this.context = null;
}
private void prepareProgressDialog()
{
if (this.context != null)
{
this.progressDialog = new ProgressDialog(this.context);
this.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
this.progressDialog.setCancelable(true);
this.progressDialog.setTitle("Please Wait...");
this.progressDialog.setMessage(PROGRESS_TEXT_PREPARING);
this.progressDialog.setProgress(Integer.parseInt(PROGRESS_PERCENT_PREPARING));
}
}
private String getPostResponse(String url)
{
byte[] result;
String str = "";
HttpClient client = new DefaultHttpClient();
HttpPost http = new HttpPost(url);
// set up post data
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
for (String key : this.mData.keySet()) {
nameValuePair.add(new BasicNameValuePair(key, this.mData.get(key)));
}
UrlEncodedFormEntity urlEncodedFormEntity;
try
{
urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePair);
http.setEntity(urlEncodedFormEntity);
this.publishProgress(PROGRESS_TEXT_CONNECTION_SERVER, PROGRESS_PERCENT_CONNECTION_SERVER);
HttpResponse response = client.execute(http);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpURLConnection.HTTP_OK)
{
this.publishProgress(PROGRESS_TEXT_PARSING, PROGRESS_PERCENT_PARSING);
result = EntityUtils.toByteArray(response.getEntity());
str = new String(result, HTTP.UTF_8);
}
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
return str;
}
private String getGetResponse(String url)
{
byte[] result;
String str = "";
HttpClient client = new DefaultHttpClient();
try
{
// set up get data and URL
Uri.Builder uri = Uri.parse(url).buildUpon();
for (String key : this.mData.keySet()) {
uri.appendQueryParameter(key, this.mData.get(key));
}
HttpGet http = new HttpGet(String.valueOf(uri));
this.publishProgress(PROGRESS_TEXT_CONNECTION_SERVER, PROGRESS_PERCENT_CONNECTION_SERVER);
HttpResponse response = client.execute(http);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpURLConnection.HTTP_OK)
{
this.publishProgress(PROGRESS_TEXT_PARSING, PROGRESS_PERCENT_PARSING);
result = EntityUtils.toByteArray(response.getEntity());
str = new String(result, HTTP.UTF_8);
}
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
return str;
}
public void setParameters(HashMap<String, String> httpRequestParameters)
{
this.mData = httpRequestParameters;
}
@Override
protected String doInBackground(Object... params)
{
// Ensure that we got, URL, http method and Callback
if (params.length != 3)
{
this.cancel(true);
}
else
{
if ((params[2] instanceof WebServiceAsyncTaskCallback))
{
this.callbackClass = ((WebServiceAsyncTaskCallback)params[2]);
}
else
{
this.cancel(true);
}
try {
URL url = new URL((String)params[0]);
} catch (MalformedURLException e) {
this.callbackClass.onError("First param must be a valid URL. (" + params[0] + " given)");
this.cancel(true);
}
if (!((String)params[1]).equals(POST) && !((String)params[1]).equals(GET))
{
this.callbackClass.onError("Second parameters must be " + this.getClass().getName() + " POST or GET constant");
this.cancel(true);
}
}
String str = "";
//IS OUR REQUEST A POST
if (params.length > 1)
{
if (((String)params[1]).toUpperCase().equals(WebServiceAsyncTask.POST))
{
str = getPostResponse(((String)params[0]));
}
else if(((String)params[1]).toUpperCase().equals(WebServiceAsyncTask.GET)) //THEN GET
{
str = getGetResponse(((String)params[0]));
}
}
return str;
}
@Override
protected void onPostExecute(String result)
{
this.mData = null;
if (this.context != null)
{
this.publishProgress(PROGRESS_TEXT_END, PROGRESS_PERCENT_END);
this.progressDialog.dismiss();
}
if (this.callbackClass != null)
{
this.callbackClass.callbackMethod(result);
}
}
@Override
protected void onPreExecute()
{
if (this.context != null)
{
this.prepareProgressDialog();
this.progressDialog.show();
}
}
@Override
protected void onProgressUpdate(String... values) {
if (this.context != null)
{
this.progressDialog.setMessage(values[0]);
this.progressDialog.setProgress(Integer.parseInt(values[1]));
}
}
}
/**
* Allow to easily get the server response
*/
abstract class WebServiceAsyncTaskCallback{
/**
* Return the server response as String
* @param result server response as a String
*/
abstract void callbackMethod(String result);
/**
* This method is design to report simple errors for development phase.
* @param errMessage contains error message
*/
protected void onError(String errMessage){};
;
}