JobScheduler es un servicio del sistema Android, presentado en API 21 (Android 5.0 Lollipop), que permite a las aplicaciones programar la ejecución de tareas en segundo plano basadas en condiciones determinadas. A diferencia de AlarmManager, JobScheduler no requiere una hora exacta de ejecución — el propio sistema determina el momento óptimo combinando los requisitos de la aplicación con el estado actual del dispositivo. Según Android Developers, 2026, el servicio admite criterios de red, carga, estado del almacenamiento y reposo del dispositivo.
Puntos clave
JobScheduler es un servicio del sistema Android que agrupa múltiples tareas en segundo plano en lotes para reducir el consumo de energía. En lugar de que cada aplicación active el dispositivo para ejecutar su propia tarea, JobScheduler las agrupa y las ejecuta en el momento óptimo cuando el dispositivo ya está activo. Esto prolonga significativamente la duración de la batería.
Antes de JobScheduler, los desarrolladores usaban AlarmManager y BroadcastReceiver para tareas en segundo plano. El problema de este enfoque era que cada aplicación activaba el dispositivo de forma independiente, lo que provocaba un rápido agotamiento de la batería. JobScheduler resolvió este problema introduciendo una ventana de ejecución por lotes, dentro de la cual el sistema lanza todas las tareas programadas de diferentes aplicaciones simultáneamente.
El principio de funcionamiento se basa en un objeto JobInfo que la aplicación pasa a JobScheduler. El sistema guarda la tarea y la ejecuta cuando se cumplen todas las condiciones especificadas. A diferencia de WorkManager, JobScheduler no garantiza el reinicio en caso de fallo — si una tarea lanza una excepción, el desarrollador debe reprogramarla manualmente.
JobScheduler utiliza una arquitectura basada en JobService y JobInfo. JobInfo describe la tarea y sus condiciones, JobService contiene la lógica de ejecución. La aplicación registra la tarea a través de getSystemService(JobScheduler.class) y llama a schedule(jobInfo). El sistema se encarga de la planificación.
JobService es una clase abstracta que extiende Service. Tiene dos métodos clave: onStartJob (se llama al iniciar la tarea) y onStopJob (se llama cuando el sistema detiene la tarea forzosamente). JobInfo se crea mediante el Builder y contiene todos los parámetros de la tarea: identificador, condiciones, restricciones de tiempo.
public class SyncJobService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
// Se ejecuta en el hilo principal
Thread thread = new Thread(() -> {
performSync();
jobFinished(params, false);
});
thread.start();
return true; // true = el trabajo continúa
}
@Override
public boolean onStopJob(JobParameters params) {
return true; // true = reprogramar tarea
}
}
JobScheduler permite establecer varios criterios simultáneamente: tipo de red (NETWORK_TYPE_ANY, NOT_ROAMING, UNMETERED), estado de carga (requiresCharging), nivel de batería (requiresBatteryNotLow), estado del almacenamiento (requiresStorageNotLow) y modo reposo (requiresDeviceIdle). La tarea se ejecuta solo cuando se cumplen todos los criterios.
JobInfo.Builder proporciona opciones flexibles para cada tarea en segundo plano. La combinación correcta de parámetros permite equilibrar la puntualidad de la ejecución y el consumo de energía.
| Método | Descripción | Ejemplo |
|---|---|---|
| setRequiredNetworkType | Tipo de red requerido | NETWORK_TYPE_UNMETERED |
| setRequiresCharging | Dispositivo cargando | true |
| setRequiresDeviceIdle | Dispositivo en reposo | true |
| setOverrideDeadline | Tiempo máximo de espera (ms) | 300000 |
| setMinimumLatency | Retardo mínimo (ms) | 60000 |
| setPeriodic | Ejecución periódica (ms) | 3600000 |
| setBackoffCriteria | Estrategia de reintento en fallo | LINEAR / EXPONENTIAL |
Un parámetro importante es setOverrideDeadline. Si se especifica una fecha límite, el sistema garantiza que la tarea se ejecutará para ese momento, incluso si no se cumplen todas las condiciones. Esto es útil para tareas con tiempo crítico de ejecución, como la sincronización cada 6 horas.
Un escenario típico es la sincronización de datos al conectarse a Wi-Fi y cargar el dispositivo. La aplicación crea un JobInfo con los criterios correspondientes y lo pasa a JobScheduler. El sistema ejecuta la tarea cuando se cumplen las condiciones favorables.
ComponentName serviceName = new ComponentName(this, SyncJobService.class);
JobInfo jobInfo = new JobInfo.Builder(JOB_ID_SYNC, serviceName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.setOverrideDeadline(6 * 60 * 60 * 1000) // 6 horas
.build();
JobScheduler scheduler = (JobScheduler)
getSystemService(Context.JOB_SCHEDULER_SERVICE);
scheduler.schedule(jobInfo);
El JobService debe registrarse en AndroidManifest.xml con el permiso BIND_JOB_SERVICE. En el método onStartJob es importante llamar a jobFinished después de completar el trabajo — de lo contrario, el sistema considerará que la tarea se está ejecutando indefinidamente y puede detenerla forzosamente.
<service
android:name=".SyncJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
JobScheduler tiene varias limitaciones. Primero, solo está disponible en Android 5+ — las versiones anteriores requieren una alternativa. Segundo, el sistema puede retrasar las tareas de aplicaciones usadas con poca frecuencia, especialmente en Android 9+ con App Standby Buckets. Tercero, JobScheduler no proporciona un mecanismo de reinicio garantizado en caso de fallo.
Google recomienda usar WorkManager en lugar de usar JobScheduler directamente. WorkManager utiliza JobScheduler internamente en Android 5+, pero añade soporte para versiones anteriores, garantía de ejecución, cadenas de tareas y observación del estado a través de LiveData. Si tu aplicación solo soporta Android 8+ y no requiere lógica compleja de tareas en segundo plano, JobScheduler aún puede estar justificado.
Para depurar JobScheduler, usa dumpsys jobscheduler a través de ADB: el comando muestra todas las tareas programadas, su estado, tiempo restante e historial de ejecución. Para una aplicación específica: adb shell dumpsys jobscheduler | grep package_name. Esto permite verificar si la tarea está registrada, qué condiciones tiene y por qué no se ejecuta. También puedes usar JobScheduler.getPendingJob() para comprobar el estado de la tarea mediante programación. Además, se puede usar Android Studio Profiler para analizar el consumo de energía durante la ejecución de tareas. Para aplicaciones en Android 5+, JobScheduler sigue siendo una herramienta fiable para tareas en segundo plano imprecisas con condiciones de red y carga.
Por defecto, JobService se ejecuta en el hilo principal, por lo que todas las operaciones bloqueantes requieren crear un hilo separado o usar AsyncTask. JobScheduler no proporciona un grupo de hilos incorporado, a diferencia de WorkManager. El desarrollador gestiona los hilos y la sincronización de forma independiente. Se recomienda usar ThreadPoolExecutor para tareas paralelas y Handler para la comunicación con el hilo principal. En onStopJob, es importante interrumpir correctamente los hilos en ejecución para evitar fugas.
JobScheduler admite tareas periódicas a través del método setPeriodic(long intervalMillis). El intervalo mínimo es de 15 minutos. Sin embargo, a diferencia de WorkManager, JobScheduler no garantiza el cumplimiento exacto del intervalo — el sistema puede desplazar la ejecución para agruparla con otras tareas. El método setPeriodic tampoco admite un intervalo flexible (ventana flexible), que apareció en versiones posteriores de la API. Para una ejecución periódica precisa, usa AlarmManager en combinación con BroadcastReceiver.
A partir de Android 9, Google introdujo App Standby Buckets, que clasifica las aplicaciones por frecuencia de uso: Active, Working Set, Frequent, Rare. Las aplicaciones en la categoría Rare experimentan retrasos de hasta 24 horas en la ejecución de tareas de JobScheduler. Los desarrolladores solo pueden influir en la categoría mediante la calidad de la aplicación — los mecanismos del sistema aumentan automáticamente la prioridad de las aplicaciones con las que el usuario interactúa regularmente. JobScheduler tiene en cuenta esta clasificación, y una tarea de una aplicación Rare solo se ejecutará en la ventana de mantenimiento. Para las aplicaciones de la categoría Active (las más usadas), los retrasos son mínimos y las tareas se ejecutan casi inmediatamente cuando se cumplen las condiciones.
Para tareas periódicas con hora exacta, JobScheduler no es adecuado — usa AlarmManager. Para tareas cortas únicas — Foreground Service con notificación. JobScheduler es óptimo para tareas donde la eficiencia energética importa más que la precisión horaria: sincronización, descarga de actualizaciones, procesamiento por lotes de datos. La elección correcta de la herramienta de trabajo en segundo plano afecta directamente la experiencia del usuario y la duración de la batería del dispositivo. La conclusión final: usa JobScheduler para procesamiento por lotes con condiciones, AlarmManager para tareas programadas y WorkManager como planificador universal.
Preguntas frecuentes
Sí, JobScheduler agrupa tareas de diferentes aplicaciones en lotes y las ejecuta juntas. Esta es una ventaja clave sobre AlarmManager: en lugar de que cada aplicación active el dispositivo por separado, el sistema activa el procesador una vez y procesa todas las tareas programadas.
Si no se ha llamado a jobFinished dentro de un tiempo razonable, el sistema puede llamar forzosamente a onStopJob y finalizar la tarea. Se recomienda completar una sola tarea en unos minutos y siempre llamar a jobFinished al finalizar.
En Doze Mode, JobScheduler aplaza todas las tareas hasta la siguiente ventana de mantenimiento, que ocurre periódicamente. Usar setOverrideDeadline garantiza que la tarea se ejecutará teniendo en cuenta estas ventanas, pero no necesariamente a una hora exacta.
WorkManager es una biblioteca que utiliza JobScheduler internamente en Android 5+. WorkManager añade garantía de ejecución, soporte para versiones anteriores (API 14+), cadenas de Workers, observación del estado a través de LiveData/Flow y reintento automático en fallos.
Para cancelar, usa scheduler.cancel(JOB_ID) para una tarea específica o scheduler.cancelAll() para todas las tareas de la aplicación. Asegúrate de que el Job ID coincida con el especificado al crear JobInfo, de lo contrario, la tarea no se cancelará.
Los desarrolladores deben entender que JobScheduler es una API del sistema de bajo nivel diseñada para equipos experimentados que quieren control total sobre las tareas en segundo plano del dispositivo. Para la mayoría de las aplicaciones, WorkManager proporciona la misma funcionalidad con una API más simple, segura y moderna para Android.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también