studio onpostexecute new hilos funciona examples como asynctask android

onpostexecute - AsyncTask de Android: evita la ejecución de varias instancias



hilos asynctask android (7)

¿Qué tal si envuelve su lógica de control de qué enviar y enviar en un método synchronized ? Este enfoque parece funcionar para nosotros.

Tengo AsyncTask que procesa algunas cosas HTTP de fondo. AsyncTask se ejecuta según lo programado (Alarmas / servicio) y, en algún momento, el usuario lo ejecuta manualmente.

Procesé los registros de SQLite y noté publicaciones dobles en el servidor, lo que me dice que en algún momento se ejecutan tareas programadas y, al mismo tiempo, el usuario lo ejecuta manualmente, lo que hace que el mismo registro se lea y procese dos veces desde el DB. Quito los registros después de que se procesaron, pero todavía tengo esto.

¿Cómo debo manejarlo? Tal vez organizar algún tipo de cola?


Inicialice la AsyncTask a nulo. Solo crea uno nuevo si es nulo. En onPostExecute, configúrelo en nulo nuevamente, al final. Haga lo mismo en onCancelled, en caso de que el usuario cancele esto. Aquí hay un código no probado para ilustrar la idea básica.

import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.Button; public class FooActivity extends Activity { private class MyAsyncTask extends AsyncTask<Foo, Foo, Foo> { @Override protected void onPostExecute(Foo foo) { // do stuff mMyAsyncTask = null; } @Override protected void onCancelled() { // TODO Auto-generated method stub mMyAsyncTask = null; } @Override protected Foo doInBackground(Foo... params) { try { // dangerous stuff } catch (Exception e) { // handle. Now we know we''ll hit onPostExecute() } return null; } } private MyAsyncTask mMyAsyncTask = null; @Override public void onCreate(Bundle bundle) { Button button = (Button) findViewById(R.id.b2); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (mMyAsyncTask == null) { mMyAsyncTask = new MyAsyncTask(); mMyAsyncTask.execute(null); } } }); }

}


O bien, puede intentar esto para ver si la tarea se está ejecutando actualmente o no:

if (katitsAsyncTask.getStatus().equals(AsyncTask.Status.FINISHED)) katitsAsyncTask.execute(); else // wait until it''s done.


Podrías mantener el estado de la tarea en preferencias compartidas. Compruebe el valor (Booleano tal vez) antes de iniciar la tarea. Establezca el estado en finalizado (¿verdadero?) En onPostExecute y falso en onPreExecute o en el constructor


Sé que esto fue hace un tiempo, y ya resolviste tu problema. Pero acabo de tener un problema similar. La sugerencia de Reno me puso en el camino correcto, pero para aquellos a los que les ha resultado difícil llenar los vacíos. Aquí es cómo superé un problema similar al de katit.

Quería que una AsyncTask en particular solo se ejecutara si no se estaba ejecutando actualmente. Y como un adelanto de la sugerencia de Reno, la interfaz AsyncTask ha sido creada para manejar todos los procesos esenciales de manera adecuada para tratar los hilos para Android. Lo que significa que el Ejecutor está integrado. Como sugiere este blog :

"Cuando se invoca execute (Object ... params) en una AsyncTask, la tarea se ejecuta en un subproceso en segundo plano. Dependiendo de la plataforma, AsyncTasks puede ejecutarse en serie (pre 1.6 y potencialmente nuevamente en 4+), o simultáneamente (1.6-3.2) .

Para estar seguro de ejecutar en serie o concurrentemente según lo requiera, a partir del nivel de API 11 en adelante, puede utilizar el método executeOnExecutor (Ejecutor del ejecutor, Objeto .. parámetros) y suministrar un ejecutor. La plataforma proporciona dos ejecutores para mayor comodidad, accesibles como AsyncTask.SERIAL_EXECUTOR y AsyncTask.THREAD_POOL_EXECUTOR respectivamente. "

Así que con esto en mente, puede realizar el bloqueo de subprocesos a través de la interfaz de AsyncTask, también implica que simplemente puede usar AsyncTasks.getStatus () para manejar el bloqueo de subprocesos, como sugiere DeeV en esta post .

En mi código, logré esto por:

Creando una variable global definida como:

private static AsyncTask<String, Integer, String> mTask = null;

Y en onCreate, inicializándolo como una instancia de mi AsyncTask llamada CalculateSpecAndDraw:

mTask = new CalculateAndDrawSpec();

Ahora, cuando quiera llamar a esto AsyncTask, envuelvo la ejecución con lo siguiente:

if(mTask.getStatus() == AsyncTask.Status.FINISHED){ // My AsyncTask is done and onPostExecute was called mTask = new CalculateAndDrawSpec().execute(Integer.toString(progress)); }else if(mTask.getStatus() == AsyncTask.Status.PENDING){ mTask.execute(Integer.toString(progress)); }else{ Toast.makeText(PlaySpecActivity.this, "Please Wait..", 1000).show(); }

Esto genera un nuevo subproceso si está terminado, o si el estado del subproceso es PENDIENTE, el subproceso está definido pero no se ha iniciado, lo iniciamos. Pero de lo contrario, si el subproceso se está ejecutando, no lo volvemos a ejecutar, simplemente le informamos al usuario que no ha finalizado o realizamos la acción que deseamos. Luego, si desea programar el próximo evento en lugar de bloquearlo para que no se vuelva a ejecutar, consulte esta documentación sobre el uso de ejecutores.


intente tener algún valor booleano de instancia que se establezca en "verdadero" en la ejecución previa de asynctask y luego "falso" en postexecute. Entonces tal vez en doinbackground verifique si ese booleano es verdadero. si es así, entonces llame a cancelar en esa tarea duplicada en particular.


Puede ejecutar su AsyncTask''s en un Executor utilizando executeOnExecutor()

Para asegurarse de que los subprocesos se estén ejecutando en serie, utilice: SERIAL_EXECUTOR .

Misc: Cómo usar un Ejecutor

Si varias actividades están accediendo a su base de datos, ¿por qué no crea una especie de ayudante de base de datos de pasarela y utiliza el bloque synchronized para garantizar que solo un subproceso tenga acceso al mismo en un instante?