Ejemplo de AsyncTask Android

Yo estaba leyendo sobre AsyncTask , y probé el programa simple a continuación. Pero no parece funcionar. ¿Cómo puedo hacer que funcione?

 package com.test; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.provider.Settings.System; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.view.View.OnClickListener; public class AsyncTaskActivity extends Activity { Button btn; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) findViewById(R.id.button1); btn.setOnClickListener((OnClickListener) this); } public void onClick(View view){ new LongOperation().execute(""); } private class LongOperation extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... params) { for(int i=0;i<5;i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } TextView txt = (TextView) findViewById(R.id.output); txt.setText("Executed"); return null; } @Override protected void onPostExecute(String result) { } @Override protected void onPreExecute() { } @Override protected void onProgressUpdate(Void... values) { } } } 

Sólo estoy tratando de cambiar la etiqueta después de 5 segundos en el proceso de fondo.

Este es mi main.xml :

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:indeterminate="false" android:max="10" android:padding="10dip"> </ProgressBar> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start Progress" > </Button> <TextView android:id="@+id/output" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Replace"/> </LinearLayout> 

Ok, está intentando acceder a la GUI a través de otro hilo. Esto, en general, no es una buena práctica.

AsyncTask ejecuta todo en doInBackground() dentro de otro subproceso, que no tiene acceso a la GUI donde están sus vistas.

preExecute() y postExecute() ofrecen acceso a la interfaz gráfica de usuario antes y después de que el levantamiento pesado ocurre en este nuevo hilo, incluso puede pasar el resultado de la operación larga a postExecute() para mostrar los resultados del procesamiento.

Vea estas líneas donde más tarde actualiza su TextView:

 TextView txt = (TextView) findViewById(R.id.output); txt.setText("Executed"); 

PostExecute() en PostExecute()

A continuación, verá el texto de TextView actualizado después de completar el doInBackground .

EDIT: me di cuenta de que su oyente onClick no verifica para ver qué vista se ha seleccionado. Encuentro que la manera más fácil de hacer esto es vía las declaraciones del interruptor. Tengo una clase completa editada a continuación con todas las sugerencias para ahorrar confusión.

 import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.provider.Settings.System; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.view.View.OnClickListener; public class AsyncTaskActivity extends Activity implements OnClickListener { Button btn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) findViewById(R.id.button1); // because we implement OnClickListener we only have to pass "this" // (much easier) btn.setOnClickListener(this); } public void onClick(View view) { // detect the view that was "clicked" switch (view.getId()) { case R.id.button1: new LongOperation().execute(""); break; } } private class LongOperation extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... params) { for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.interrupted(); } } return "Executed"; } @Override protected void onPostExecute(String result) { TextView txt = (TextView) findViewById(R.id.output); txt.setText("Executed"); // txt.setText(result); // might want to change "executed" for the returned string passed // into onPostExecute() but that is upto you } @Override protected void onPreExecute() {} @Override protected void onProgressUpdate(Void... values) {} } } 

Mi respuesta completa está aquí , pero aquí hay una imagen explicativa para complementar las otras respuestas en esta página. Para mí, la comprensión de dónde iban todas las variables era la parte más confusa del principio.

Introduzca aquí la descripción de la imagen

Estoy seguro de que se está ejecutando correctamente, pero usted está tratando de cambiar los elementos de la interfaz de usuario en el hilo de fondo y eso no va a hacer.

Revise su llamada y AsyncTask de la siguiente manera:

Clase de llamada

Nota: personalmente, sugiero usar onPostExecute() dondequiera que ejecute el hilo de AsyncTask y no en la clase que extiende AsyncTask mismo. Creo que hace que el código más fácil de leer, especialmente si usted necesita el AsyncTask en múltiples lugares de manipulación de los resultados ligeramente diferentes.

 new LongThread() { @Override public void onPostExecute(String result) { TextView txt = (TextView) findViewById(R.id.output); txt.setText(result); } }.execute(""); 

LongThread class (extends AsyncTask):

 @Override protected String doInBackground(String... params) { for(int i = 0; i < 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } return "Executed"; } 

Concepto y código aquí

He creado un ejemplo simple para usar AsyncTask de Android. Comienza con onPreExecute(), doInBackground(), publishProgress() y finalmente onProgressUpdate() .

En este doInBackground () funciona como un hilo de fondo, mientras que otros trabajos en el hilo de interfaz de usuario. No puede acceder a un elemento de interfaz de usuario en doInBackground (). La secuencia es la misma que he mencionado.

Sin embargo, si necesita actualizar cualquier widget de doInBackground puede publishProgress de doInBackground que llamará onProgressUpdate para actualizar su widget de interfaz de usuario.

 class TestAsync extends AsyncTask<Void, Integer, String> { String TAG = getClass().getSimpleName(); protected void onPreExecute (){ super.onPreExecute(); Log.d(TAG + " PreExceute","On pre Exceute......"); } protected String doInBackground(Void...arg0) { Log.d(TAG + " DoINBackGround","On doInBackground..."); for(int i=0; i<10; i++){ Integer in = new Integer(i); publishProgress(i); } return "You are at PostExecute"; } protected void onProgressUpdate(Integer...a){ super.onProgressUpdate(a); Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]); } protected void onPostExecute(String result) { super.onPostExecute(result); Log.d(TAG + " onPostExecute", "" + result); } } 

Llámalo así en tu actividad:

 new TestAsync().execute(); 

Referencia del desarrollador aquí

Mueva estas dos líneas:

 TextView txt = (TextView) findViewById(R.id.output); txt.setText("Executed"); 

Fuera del método doInBackground de doInBackground y ponerlos en el método onPostExecute . Su AsyncTask debe ser algo como esto:

 private class LongOperation extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... params) { try { Thread.sleep(5000); // no need for a loop } catch (InterruptedException e) { Log.e("LongOperation", "Interrupted", e); return "Interrupted"; } return "Executed"; } @Override protected void onPostExecute(String result) { TextView txt = (TextView) findViewById(R.id.output); txt.setText(result); } } 

El ejemplo más corto para hacer algo asincrónicamente:

 class MyAsyncTask extends android.os.AsyncTask { @Override protected Object doInBackground(Object[] objects) { //do something asynchronously return null; } } 

Para ejecutarlo:

 (new MyAsyncTask()).execute(); 

Cuando se ejecuta una tarea asincrónica, la tarea pasa por 4 pasos:

  1. OnPreExecute ()
  2. DoInBackground (Params …)
  3. OnProgressUpdate (Progreso …)
  4. OnPostExecute (Resultado)

A continuación se muestra un ejemplo de demostración

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { protected Long doInBackground(URL... urls) { int count = urls.length; long totalSize = 0; for (int i = 0; i < count; i++) { totalSize += Downloader.downloadFile(urls[i]); publishProgress((int) ((i / (float) count) * 100)); // Escape early if cancel() is called if (isCancelled()) break; } return totalSize; } protected void onProgressUpdate(Integer... progress) { setProgressPercent(progress[0]); } protected void onPostExecute(Long result) { showDialog("Downloaded " + result + " bytes"); } } 

Y una vez creada, una tarea se ejecuta muy sencillamente:

  new DownloadFilesTask().execute(url1, url2, url3); 

Espero que esto ayude…

Cuando está en el subproceso de trabajo, no puede manipular directamente elementos de la interfaz de usuario en Android.

Cuando utilice AsyncTask, comprenda los métodos de devolución de llamada.

Por ejemplo:

 public class MyAyncTask extends AsyncTask<Void, Void, Void>{ @Override protected void onPreExecute() { // Here you can show progress bar or something on the similar lines. // Since you are in a UI thread here. super.onPreExecute(); } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); // After completing execution of given task, control will return here. // Hence if you want to populate UI elements with fetched data, do it here. } @Override protected void onProgressUpdate(Void... values) { super.onProgressUpdate(values); // You can track you progress update here } @Override protected Void doInBackground(Void... params) { // Here you are in the worker thread and you are not allowed to access UI thread from here. // Here you can perform network operations or any heavy operations you want. return null; } } 

FYI: Para acceder al subproceso de UI desde un subproceso de trabajo, utilice el método runOnUiThread () o el método de publicación en su vista.

Por ejemplo:

 runOnUiThread(new Runnable() { textView.setText("something."); }); or yourview.post(new Runnable() { yourview.setText("something"); }); 

Esto le ayudará a saber las cosas mejor. Por lo tanto, en su caso, debe configurar su texto en el método onPostExecute ().

Recomendaría hacer su vida más fácil usando esta biblioteca para los trabajos de fondo https://github.com/Arasthel/AsyncJobLibrary

Es tan simple

 AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() { @Override public void doOnBackground() { startRecording(); } }); 

Ejemplo de tarea asíncrona con solicitud POST:

 List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("key1", "value1")); params.add(new BasicNameValuePair("key1", "value2")); new WEBSERVICEREQUESTOR(URL, params).execute(); class WEBSERVICEREQUESTOR extends AsyncTask<String, Integer, String> { String URL; List<NameValuePair> parameters; private ProgressDialog pDialog; public WEBSERVICEREQUESTOR(String url, List<NameValuePair> params) { this.URL = url; this.parameters = params; } @Override protected void onPreExecute() { pDialog = new ProgressDialog(LoginActivity.this); pDialog.setMessage("Processing Request..."); pDialog.setIndeterminate(false); pDialog.setCancelable(false); pDialog.show(); super.onPreExecute(); } @Override protected String doInBackground(String... params) { try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpEntity httpEntity = null; HttpResponse httpResponse = null; HttpPost httpPost = new HttpPost(URL); if (parameters != null) { httpPost.setEntity(new UrlEncodedFormEntity(parameters)); } httpResponse = httpClient.execute(httpPost); httpEntity = httpResponse.getEntity(); return EntityUtils.toString(httpEntity); } catch (Exception e) { } return ""; } @Override protected void onPostExecute(String result) { pDialog.dismiss(); try { } catch (Exception e) { } super.onPostExecute(result); } } 
  private class AsyncTaskDemo extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); // Showing progress dialog progressDialog = new ProgressDialog(this); progressDialog.setMessage("Loading..."); progressDialog.setCancelable(false); progressDialog.show(); } @Override protected Void doInBackground(Void... arg0) { //do code here return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); // Dismiss the progress dialog if (progressDialog.isShowing()) { progressDialog.dismiss(); } } @Override protected void onCancelled() { super.onCancelled(); progressDialog.dismiss(); Toast toast = Toast.makeText(getActivity(), "Error is occured due to some probelm", Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP, 25, 400); toast.show(); } } 

Simplemente:

 LongOperation MyTask = new LongOperation(); MyTask.execute(); 

Debes declarar el botón onclicklistener, una vez que haga clic en él llama a AsyncTask class DownloadJson, el proceso se mostrará a continuación:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) findViewById(R.id.button1); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new DownloadJson().execute(); } }); } 

  // DownloadJSON AsyncTask private class DownloadJson extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(Void... params) { newlist = new ArrayList<HashMap<String, String>>(); json = jsonParser.makeHttpRequest(json, "POST"); try { newarray = new JSONArray(json); for (int i = 0; i < countdisplay; i++) { HashMap<String, String> eachnew = new HashMap<String, String>(); newobject = newarray.getJSONObject(i); eachnew.put("id", newobject.getString("ID")); eachnew.put("name", newobject.getString("Name")); newlist.add(eachnew); } } } catch (JSONException e) { Log.e("Error", e.getMessage()); e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void args) { newlisttemp.addAll(newlist); NewAdapterpager newadapterpager = new NewAdapterpager(ProcesssActivitypager.this,newlisttemp); newpager.setAdapter(newadapterpager); } } 

Cambie el código como se indica a continuación:

 @Override protected void onPostExecute(String result) { runOnUiThread(new Runnable() { public void run() { TextView txt = (TextView) findViewById(R.id.output); txt.setText("Executed"); } }); } 
  • Si AsyncTask no es una clase interna ... - algunas preguntas
  • Conseguir un no puede hacer una redfrence estática a una no estática methed cuando llamo AsyncTask <Void.exicute
  • Android: Llamar a los métodos en el subproceso de interfaz de usuario de AsyncTask método doInBackground
  • Cargando datos de forma eficaz en RecycleView
  • ¿Cuál es la diferencia entre largo y largo en código android?
  • ¿Cómo uso el depurador de Eclipse en un AsyncTask cuando se desarrolla para Android?
  • ¿Por qué no AsyncTasks siempre funcionan dentro de un onClickListener?
  • ¿Cómo puedo hacer conexiones de URL asíncronas en Android?
  • Android AsyncTask - una subclase por operación de base de datos?
  • Asyntask: ¿por qué actualizar el hilo de la interfaz de usuario en doInbackground se encontrará con el error?
  • Cómo pasar el parámetro de tipo byte a la función AsyncTask?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.