Estaba leyendo sobre AsyncTask
, y probé el programa simple a continuación. pero no parece funcionar. ¿Cómo puedo hacer que funcione?
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) {
}
}
}
Solo intento cambiar la etiqueta después de 5 segundos en el proceso en segundo plano.
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>
android
android-asynctask
zorro
fuente
fuente
Respuestas:
Ok, estás intentando acceder a la GUI a través de otro hilo. Esto, en general, no es una buena práctica.
AsyncTask ejecuta todo
doInBackground()
dentro de otro hilo, que no tiene acceso a la GUI donde están sus vistas.preExecute()
ypostExecute()
ofrecerle acceso a la GUI antes y después de que ocurra el trabajo pesado en este nuevo hilo, e incluso puede pasar el resultado de la operación largapostExecute()
para luego mostrar los resultados del procesamiento.Vea estas líneas donde luego está actualizando su TextView:
Póngalos adentro
onPostExecute()
.Luego verá su texto TextView actualizado después de que se
doInBackground
complete.Noté que su oyente onClick no verifica qué Vista ha sido seleccionada. Encuentro que la forma más fácil de hacerlo es a través de declaraciones de cambio. Tengo una clase completa editada a continuación con todas las sugerencias para evitar confusiones.
fuente
onPostExecute(String result)
método. Para los futuros lectores, sería más claro que el argumento está poblado por el valor de retorno dedoInBackground(String... params)
.Mi respuesta completa está aquí , pero aquí hay una imagen explicativa para complementar las otras respuestas en esta página. Para mí, entender hacia dónde iban todas las variables fue la parte más confusa al principio.
fuente
params
es una matriz (En el ejemplo anterior, era unaString
matriz). Esto le permite pasar múltiples parámetros del mismo tipo. A continuación, puede acceder a esos parámetros conparams[0]
,params[1]
,params[2]
, etc. En el ejemplo, sólo había una solaString
en laparams
matriz. Si necesita pasar varios parámetros de diferentes tipos (por ejemplo, ayString
anint
), consulte esta pregunta .Estoy seguro de que se está ejecutando correctamente, pero está intentando cambiar los elementos de la interfaz de usuario en el subproceso de fondo y eso no funcionará.
Revise su llamada y AsyncTask de la siguiente manera:
Clase de llamada
Nota: Yo personalmente sugiero usar
onPostExecute()
donde sea que ejecute su hilo AsyncTask y no en la clase que extiende AsyncTask en sí. Creo que hace que el código sea más fácil de leer, especialmente si necesita AsyncTask en varios lugares para manejar los resultados de manera ligeramente diferente.Clase LongThread (extiende AsyncTask):
fuente
onPostExecute
en la actividad es brillante.He creado un ejemplo simple para usar AsyncTask de Android. Comienza con
onPreExecute(), doInBackground(), publishProgress()
y finalmenteonProgressUpdate()
.En esto, doInBackground () funciona como un subproceso de fondo, mientras que otros funciona en el subproceso de la interfaz de usuario. No puede acceder a un elemento de la interfaz de usuario en doInBackground (). La secuencia es la misma que he mencionado.
Sin embargo, si necesita actualizar cualquier tipo de artilugio de
doInBackground
, se puedepublishProgress
partir dedoInBackground
la cual va a llamaronProgressUpdate
para actualizar su widget de interfaz de usuario.Llámalo así en tu actividad:
Referencia del desarrollador aquí
fuente
Mueve estas dos líneas:
fuera de su AsyncTask's
doInBackground
método y ponerlos en elonPostExecute
método. SuAsyncTask
debe ser algo como esto:fuente
AsyncTask
, que mi respuesta aborda; y enviando un valor de un servicio al hilo ui, que aborda la otra discusión. Estos problemas son independientes.Antecedentes / Teoría
AsyncTask le permite ejecutar una tarea en un subproceso en segundo plano, mientras publica los resultados en el subproceso de la interfaz de usuario.
Implementación
AsyncTask es una clase genérica. (Toma tipos parametrizados en su constructor).
Utiliza estos tres tipos genéricos:
Params
- el tipo de los parámetros enviados a la tarea tras la ejecución.Progress
- el tipo de las unidades de progreso publicadas durante el cálculo en segundo plano.Result
- el tipo del resultado del cálculo de fondo.Estos tres parámetros corresponden a tres funciones principales en las que puede anular
AsyncTask
:doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
Para ejecutar AsyncTask
execute()
con parámetros que se enviarán a la tarea en segundo plano.Lo que pasa
En el hilo principal / UI ,
onPreExecute()
se llama.En un hilo de fondo ,
doInBackground(Params...)
se llama.Params
se pasaron porexecute
.)Debe anular al menos
doInBackground()
para usar AsyncTask.Llame
publishProgress(Progress...)
para actualizar la interfaz de usuario con una pantalla de progreso (p. Ej., Animación de la interfaz de usuario o texto de registro impreso) mientras el cálculo en segundo plano aún se está ejecutando.onProgressUpdate()
de ser llamado.En el hilo de fondo se devuelve un resultado
doInBackground()
.En el hilo principal / UI ,
onPostExecute()
se llama con el resultado devuelto.Ejemplos
En ambos ejemplos, la "tarea de bloqueo" es una descarga desde la web.
Ejemplo A
El
doInBackground()
método descarga la imagen y la almacena en un objeto de tipo BitMap. ElonPostExecute()
método toma el mapa de bits y lo coloca en ImageView.Ejemplo B
Ejemplo de ejecución B
fuente
Cuando se ejecuta una tarea asincrónica, la tarea sigue cuatro pasos:
A continuación se muestra un ejemplo de demostración:
Y una vez que creó, una tarea se ejecuta de manera muy simple:
fuente
El ejemplo más corto para hacer algo de forma asincrónica:
Para ejecutarlo:
fuente
¿Cómo memorizar los parámetros utilizados en AsyncTask?
Si es nuevo en AsyncTask, es muy común confundirse al escribir AsyncTask. Los principales culpables son los parámetros utilizados en la AsyncTask, es decir,
AsyncTask<A, B, C>
. Con base en la firma A, B, C (argumentos) de los métodos, esto hace que las cosas sean aún más confusas.¡Mantenlo simple!
La clave es no memorizar . Si puede visualizar lo que su tarea realmente necesita hacer, escribir AsyncTask con la firma correcta en el primer intento sería pan comido. Solo averigua cuáles son tus
Input
,Progress
yOutput
eres, y estarás listo para comenzar.Entonces, ¿qué es una AsyncTask?
AsyncTask es una tarea en segundo plano que se ejecuta en el subproceso en segundo plano. Toma un
Input
, realizaProgress
y da unOutput
.Por ejemplo:
¿Cuál es la relación con los métodos?
¿Cómo escribir eso en el código?
¿Cómo ejecutarás esta tarea?
fuente
Cuando está en el subproceso de trabajo, no puede manipular directamente los elementos de la interfaz de usuario en Android.
Cuando utilice AsyncTask, comprenda los métodos de devolución de llamada.
Por ejemplo:
FYI: para acceder al subproceso de la interfaz de usuario desde un subproceso de trabajo, utilice el método runOnUiThread () o el método de publicación en su vista.
Por ejemplo:
Esto te ayudará a conocer mejor las cosas. Por lo tanto, en su caso, debe establecer su vista de texto en el método onPostExecute ().
fuente
Recomendaría facilitarle la vida al usar esta biblioteca para trabajos en segundo plano:
https://github.com/Arasthel/AsyncJobLibrary
Es así de simple ...
fuente
Ejemplo de tarea asíncrona con solicitud POST:
fuente
Simplemente:
fuente
Debe declarar el botón onclicklistener. Una vez que se hace clic, llama a la clase AsyncTask DownloadJson.
El proceso se mostrará a continuación:
fuente
fuente
Actualización: marzo de 2020
Según la documentación oficial del desarrollador de Android , AsyncTask ahora está en desuso.
En su lugar, se recomienda utilizar las corourines de Kotlin . Simplemente, le permite escribir tareas asincrónicas en un estilo secuencial.
fuente
Ejemplo de ejemplo de AsyncTask con progreso
fuente
Tarea ASync;
fuente
MyTask
dentro de la claseMainActivity
? ¿Es eso habitual?Mientras trabaja con AsyncTask, es necesario crear un sucesor de clase y en él registrar la implementación de los métodos necesarios para nosotros. En esta lección veremos tres métodos:
doInBackground : se ejecutará en un nuevo hilo y aquí resolveremos todas nuestras tareas difíciles. Porque un subproceso no primario no tiene acceso a la interfaz de usuario.
onPreExecute : ejecutado antes de doInBackground y tiene acceso a la interfaz de usuario
onPostExecute : ejecutado después de doInBackground (no funciona si se canceló AsyncTask, sobre esto en las próximas lecciones) y tiene acceso a la interfaz de usuario.
Esta es la clase MyAsyncTask:
Y así es como llamar a su Actividad o Fragmento:
fuente
si abre la clase AsyncTask, puede ver el código a continuación.
Funciones de AsyncTask
ejemplo
fuente
Cambie su código como se indica a continuación:
fuente