Search code examples
androidandroid-asynctaskencapsulationnetwork-connection

Android, how can i encapsulate an AsyncTask class with network connections


Im starting with android (3 days ago) and i cant get the solution for what i want. So, i read a lot of threads here about asyncTask and now im sure i got confused.

First of all, this is my first question so i hope i get this at least right.

What i want is to have a class to connect to some server and the a result from it. After that analyses the json or xml.

so this is what i did. this is my activity class (called from main one)

    public class LogIn extends Activity implements OnClickListener {

    Button btn =null;

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.login);

    btn = (Button) findViewById(R.id.btn_login);
    btn.setOnClickListener( this);
}   

public void onClick(View view) {
    HttpResponse response;
    Intent data = new Intent();
    //---get the EditText view---
    EditText txt_user = (EditText) findViewById(R.id.et_un);
    EditText txt_pwd =  (EditText) findViewById(R.id.et_pw);

    // aca tengo q llamar al conectar y chequear en BD
    ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
    postParameters.add(new BasicNameValuePair("usr", txt_user.getText().toString()));
    postParameters.add(new BasicNameValuePair("pass", txt_pwd.getText().toString()));
    String URL="whatever";
    try {
        response= new ConectServer(URL, postParameters).execute().get();

        LeerAutentificacionXml l= new LeerAutentificacionXml(response);
        String s=l.Transformar();
        data.setData(Uri.parse(s.toString()));
        setResult(RESULT_OK, data);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    //---set the data to pass back---
//  data.setData(Uri.parse(txt_user.getText().toString()+ " " + Uri.parse(txt_pwd.getText().toString())));
//  setResult(RESULT_OK, data);
    //---closes the activity---
    finish();
} }

and this is my class that connect to web services.

    public class ConectServer extends AsyncTask <Void, Void, HttpResponse> {

private String URL=null;
private ArrayList<NameValuePair> postParameters=null;
/** Single instance of our HttpClient */
private HttpClient mHttpClient;
/** The time it takes for our client to timeout */
public static final int HTTP_TIMEOUT = 30 * 1000;


  public ConectServer(String url, ArrayList<NameValuePair> p) {
      this.URL=url;
      this.postParameters=p;
  }

 private HttpClient getHttpClient() {
     if (mHttpClient == null) {
         mHttpClient = new DefaultHttpClient();
         final HttpParams params = mHttpClient.getParams();
         HttpConnectionParams.setConnectionTimeout(params, HTTP_TIMEOUT);
         HttpConnectionParams.setSoTimeout(params, HTTP_TIMEOUT);
         ConnManagerParams.setTimeout(params, HTTP_TIMEOUT);
     }
     return mHttpClient;
 }

 /**
 * Performs an HTTP Post request to the specified url with the
 * specified parameters.
 *
 * @param url The web address to post the request to
 * @param postParameters The parameters to send via the request
 * @return The result of the request
 * @throws Exception
 */
@Override
protected HttpResponse doInBackground(Void... params) {
    // TODO Auto-generated method stub
     HttpResponse response = null;
     try {
         HttpClient client = getHttpClient();
         HttpPost request = new HttpPost(this.URL);
         UrlEncodedFormEntity formEntity;
         formEntity = new UrlEncodedFormEntity(this.postParameters);
         request.setEntity(formEntity);
         response = client.execute(request);
     } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
     } catch (ClientProtocolException e) {
        e.printStackTrace();
     } catch (IOException e) {
        e.printStackTrace();
    }

    return response;
}


public void onPreExecute() {
     super.onPreExecute();

}

protected void onPostExecute(HttpResponse response) {
     super.onPostExecute(response);
}}

I read about some design patter with listener but first i would like to understand better why this is not working. Im getting an error from server and i would like to know if this is correct or which big newby fail is going on.

Thx in advance.


Solution

  • Calling asyncTask.get() waits for the AsyncTask to finish and then returns the result. It basically defeats the purpose of the AsyncTask - the whole point of AsyncTask is that long-running task executes in the background thread and UI thread is not blocked during this time. When you call .get() it blocks the UI thread waiting for background thread to finish.

    So, don't use get() and move ll actions that should happen when result is available to onPostExecute(..). Something like this:

    protected void onPostExecute(HttpResponse response) {
        super.onPostExecute(response);
        LeerAutentificacionXml l= new LeerAutentificacionXml(response);
        String s=l.Transformar();
        data.setData(Uri.parse(s.toString()));
    }
    

    Of course, you will have to pass some references (data?) to AsyncTask (via constructor or otherwise).