¿Qué cambio ocurrió realmente en Async Task después de Android Gingerbread?

¿Qué cambio hizo realmente el equipo de Android en la tarea Async después de Android 2.3. Cuando ejecuté el siguiente código, obtengo el mismo resultado en Android 2.3 y 3.0.

package com.sample.asynctask;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

public class AsyncTaskTestActivity extends Activity {
    private static final String TAG = "AsyncTaskTestActivity";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //ExecutorService executorService = Executors.newFixedThreadPool(1);
        for (int i = 1; i <= 20; i++) {
            TestTask testTask = new TestTask(i);
            testTask.execute();
        }
    }

    private static class TestTask extends AsyncTask<Void, Integer, Void> {
        int i;
        public TestTask(int i) {
            Log.i(TAG, "Constructor for " + i);
            this.i = i;
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            Log.i(TAG, "onPreExecute for " + i);
        }

        @Override
        protected Void doInBackground(Void... params) {
            Log.i(TAG, i + " Thread goes to sleep");
            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Log.i(TAG, i + " Thread wakes up");
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            Log.i(TAG, "onPostExecute for " + i);
        }
    }
}

Mi suposición en Gingerbread: 5 La tarea asíncrona se ejecuta en un grupo de subprocesos a la vez. Mi suposición en Honeycomb: 1 tarea asíncrona se ejecuta en un grupo de subprocesos a la vez. Exactamente como la ejecución concurrente.

Pero, tanto Gingerbread como Honeycomb ejecutan 5 tareas asíncronas al mismo tiempo.

Y también cuando el número de tareas asíncronas aumenta a 140. No obtengo java.util.concurrent.RejectedExecutionException .

Si mis suposiciones son correctas? ¿Qué está pasando realmente allí dentro?

preguntado el 12 de junio de 12 a las 11:06

3 Respuestas

Si mis suposiciones son correctas?

Tus suposiciones son correctas, bueno, más o menos.

¿Qué está pasando realmente allí dentro?

El ejecutor predeterminado dentro android.os.AsyncTask:

... ...

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

... ...

ha sido reiniciado en Android.app.Subproceso de actividad:

... ...

// If the app is Honeycomb MR1 or earlier, switch its AsyncTask
// implementation to use the pool executor.  Normally, we use the
// serialized executor as the default. This has to happen in the
// main thread so the main looper is set right.
if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
    AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

... ...

¿Qué cambio ocurrió realmente en Async Task después de Android Gingerbread?

Echa un vistazo a AsyncTask cambia la historia, más concretamente, éste:

17 de marzo de 2011: AsyncTask ahora usa el ejecutor de encuestas para aplicaciones hasta HC MR1 y t...

Cuando el número de tareas asíncronas aumenta a 140, no obtengo java.util.concurrent.RejectedExecutionException.

Este es un factor del número total de tareas y el tiempo de ejecución por cada tarea, en otro mundo, el número total de tareas es 140 (que es mayor que 128), sin embargo, el número total de subprocesos asignados por subprocesos en un momento dado es menor que 128, en otras palabras, siempre hay algunos subprocesos inactivos (debido a la última tarea finalizada y el recurso de liberación) disponibles en su caso. puede intentar aumentar el tiempo de ejecución para cada tarea, por ejemplo Thread.sleep(10000), esto probablemente le dará RejectedExecutionException.

Respondido el 18 de Septiembre de 12 a las 22:09

¿Y no recibo un error cuando hay más de 140 tareas asíncronas? - Anuncios

si (data.appInfo.targetSdkVersion <= 12) { AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } . así que estas líneas están haciendo ese cambio bien.genial - Anuncios

sí, estoy recibiendo RejectedExecutionException ahora. Pero aún no tengo muy claro eso: Anuncios

@Ads, simplemente hablando, 140 tareas no significa que el grupo de subprocesos deba asignar 140 subprocesos, lo que realmente importa es cuántos subprocesos se asignan en un momento dado, depende de cuánto tiempo tome cada tarea, es posible que el subproceso solo necesite 10 subprocesos para ejecutar todas las tareas. Si se envía la siguiente tarea mientras no hay subprocesos disponibles en el conjunto de subprocesos (los 128 subprocesos están ocupados), el conjunto de subprocesos generará una excepción de ejecución rechazada. - Yorkw

Este hilo describe los cambios en AsyncTask en ICS. La información la proporciona un empleado de Google, por lo que es confiable.

https://groups.google.com/forum/?fromgroups#!topic/android-developers/8M0RTFfO7-M

Respondido el 12 de junio de 12 a las 12:06

El cambio en el comportamiento de AsyncTask también requiere que se ejecute en ICS y hardware superior.

Ver: http://commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.html

Respondido el 12 de junio de 12 a las 12:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.