android - medir - ¿Qué herramientas están disponibles para probar JobScheduler?
medir hashtag twitter gratis (4)
Estamos implementando un trabajo a través de JobScheduler para la carga en segundo plano de los datos. El trabajo se disparará una vez al día. ¿Qué herramientas están disponibles para que probemos esta funcionalidad (posiblemente ADB)?
Los casos de uso son para poder simular las condiciones requeridas para la ejecución de un trabajo o simplemente decir específicamente "Ejecutar este trabajo" como parte de nuestro conjunto de pruebas automatizadas.
A partir de Android 7.0, hay un nuevo cmd
para adb shell. Y en 7.1 (solo en vista previa en este momento), adb shell cmd jobscheduler
se agregó como se puede ver aquí para forzar la ejecución de su JobScheduler. La ayuda dice:
Comandos del programador de trabajos (jobscheduler): ayuda Imprima este texto de ayuda.
corre [-f | --force] [-u | --user USER_ID] PACKAGE JOB_ID Desencadena la ejecución inmediata de un trabajo programado específico. Opciones: -f o --force: ejecuta el trabajo incluso si no se cumplen actualmente las limitaciones técnicas, como la conectividad -u o --user: especifique qué trabajo del usuario se ejecutará; el predeterminado es el usuario primario o del sistema
Con el comando adb shell dumpsys jobscheduler
usted obtiene información sobre los trabajos actualmente programados y activos.
Noté que la salida del comando difiere mucho entre Android 6 y 7. Con un dispositivo Android 5 , la salida es muy corta y, a veces, críptica. La parte interesante con los trabajos registrados se construye here y se repite a continuación para mayor comodidad, lo que debería ayudar con el descifrado:
@Override
public String toString() {
return String.valueOf(hashCode()).substring(0, 3) + ".."
+ ":[" + job.getService()
+ ",jId=" + job.getId()
+ ",u" + getUserId()
+ ",R=(" + formatRunTime(earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME)
+ "," + formatRunTime(latestRunTimeElapsedMillis, NO_LATEST_RUNTIME) + ")"
+ ",N=" + job.getNetworkType() + ",C=" + job.isRequireCharging()
+ ",I=" + job.isRequireDeviceIdle() + ",F=" + numFailures
+ ",P=" + job.isPersisted()
+ (isReady() ? "(READY)" : "")
+ "]";
}
Los dispositivos Android 7 , por otro lado, tienen una salida muy larga con información más detallada y mejor legible. También hay más características como una historia. El inconveniente es que primero debes encontrar las partes interesantes.
Sin embargo, no he encontrado una forma de forzar la ejecución de un trabajo, hay una solicitud de función para él. Vea la respuesta de p4u144.
Derecha.
Henning y P4u144 me pusieron en el camino correcto para responder esto con más detalle.
Identificar todos los trabajos registrados
Identifique su tarea con el comando adb shell dumpsys jobscheduler
.
Esto le dará una gran salida en las siguientes categorías.
- Ajustes
- Registrado XX trabajos
- Conectividad
- Alarmas
- Ocioso
- Batería
- AppIdle
- Contenido
- Historia laboral
- Cola pendiente
La categoría en la que es más probable que te interese es Registrado XX Trabajos . Esto le indica cuántos trabajos se han programado en el dispositivo.
Por ejemplo, su nombre de com.foo.bar.application
es com.foo.bar.application
debería ver una entrada como esta:
JOB #u0a93/17: eec3709 com.foo.bar.application/com.evernote.android.job.v21.PlatformJobService
u0a93 tag=*job*/com.foo.bar.application/com.evernote.android.job.v21.PlatformJobService
Source: uid=u0a93 user=0 pkg=com.foo.bar.application
JobInfo:
Service: com.foo.bar.application/com.evernote.android.job.v21.PlatformJobService
PERIODIC: interval=+15m0s0ms flex=+5m0s0ms
PERSISTED
Requires: charging=false deviceIdle=false
Network type: 2
Backoff: policy=1 initial=+30s0ms
Has early constraint
Has late constraint
Required constraints: TIMING_DELAY DEADLINE UNMETERED
Satisfied constraints: CONNECTIVITY NOT_ROAMING APP_NOT_IDLE DEVICE_NOT_DOZING
Unsatisfied constraints: TIMING_DELAY DEADLINE UNMETERED
Earliest run time: 07:23
Latest run time: 12:23
Ready: false (job=false pending=false active=false user=true)
Consejo: Use
adb shell dumpsys jobscheduler | grep com.foo.bar.application
adb shell dumpsys jobscheduler | grep com.foo.bar.application
para filtrar rápidamente la lista.
Ahora puede identificar fácilmente si su trabajo ha sido registrado con los criterios correctos.
FireBaseJobdispatcher
Si usa la FirebaseJobDispatcher
puede usar
adb shell dumpsys activity service GcmService | grep com.foo.bar.debug
com.foo.bar.debug:0 v853
u0|com.foo.bar.debug: 3
(scheduled) com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver{u=0 tag="com.foo.bar.debug.job.FetchArticlesJob" trigger=window{start=10800s,end=11700s,earliest=10448s,latest=11348s} requirements=[NET_UNMETERED,DEVICE_IDLE] attributes=[PERSISTED,RECURRING] scheduled=-351s last_run=N/A jid=N/A status=PENDING retries=0 client_lib=FIREBASE_JOB_DISPATCHER-1}
(scheduled) com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver{u=0 tag="com.foo.bar.debug.job.FetchNotificationGroupsJob" trigger=window{start=86400s,end=129600s,earliest=86048s,latest=129248s} requirements=[NET_CONNECTED,CHARGING] attributes=[PERSISTED,RECURRING] scheduled=-351s last_run=N/A jid=N/A status=PENDING retries=0 client_lib=FIREBASE_JOB_DISPATCHER-1}
(scheduled) com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver{u=0 tag="com.foo.bar.debug.job.RemoveUnusedRealmArticlesJob" trigger=window{start=577980s,end=608400s,earliest=521961s,latest=552381s} requirements=[NET_ANY] attributes=[PERSISTED,RECURRING] scheduled=-56018s last_run=N/A jid=N/A status=PENDING retries=0 client_lib=FIREBASE_JOB_DISPATCHER-1}
(finished) [com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver:com.foo.bar.debug.job.UpdateNotificationGroupJob,u0]
(finished) [com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver:com.foo.bar.debug.job.UpdatePushTokenJob,u0]
(finished) [com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver:com.foo.bar.debug.job.FetchArticlesJob,u0]
para comprobar si su servicio ha sido programado o ejecutado.
Fuerza tu tarea para correr
Al crear un Job
se obtiene un JOB_ID
devuelto.
Utilice este JOB_ID
para forzar la ejecución del trabajo.
Puede hacerlo utilizando el comando de adb shell cmd jobscheduler run
, (requiere Android 7.1 o superior).
Por ejemplo, su nombre de com.foo.bar.application
es com.foo.bar.application
y el JOB_ID
era 1. Ahora puede ejecutar su tarea a través de adb
adb shell cmd jobscheduler run -f com.foo.bar.application 1
No olvide la opción -f
, ya que esto obliga a la tarea a ejecutarse incluso si no se cumplen las restricciones establecidas.
Evernote Android Job Lib
Por último, pero ciertamente no menos importante.
Usa la maravillosa biblioteca de Evernote para esto.
Permite un backporting fácil de JobScheduler
en niveles de API más bajos utilizando JobScheduler
, GcmNetworkManager
o AlarmManager
dependiendo de su nivel de API.
Editar 24/08
Aún mejor utilizar la biblioteca de despacho de trabajo de base de fuego.
Firebase JobDispatcher es una biblioteca para programar trabajos en segundo plano en su aplicación de Android. Proporciona una API compatible con JobScheduler que funciona en todas las versiones recientes de Android (nivel API 9+) que tienen los servicios de Google Play instalados.
Espero que esto haya ayudado.
Gracias
Esto está funcionando para mí, sin la necesidad de usar comandos adb. Requiere minSdk 21
@RunWith(AndroidJUnit4.class)
@TargetApi(VERSION_CODES.LOLLIPOP)
public abstract class BaseJobServiceTest {
protected final Context context() {
return InstrumentationRegistry.getTargetContext();
}
protected final void launchJobAndWait(JobInfo jobInfo) throws InterruptedException {
JobScheduler scheduler = (JobScheduler) context().getSystemService(Context.JOB_SCHEDULER_SERVICE);
scheduler.schedule(jobInfo);
while (jobExecutionPending(scheduler, jobInfo)) {
Thread.sleep(50);
}
}
private boolean jobExecutionPending(JobScheduler scheduler, JobInfo jobInfo) {
if (VERSION.SDK_INT >= VERSION_CODES.N) {
return scheduler.getPendingJob(jobInfo.getId()) != null;
}
List<JobInfo> scheduledJobs = scheduler.getAllPendingJobs();
for (int i = 0, size = scheduledJobs.size(); i < size; i++) {
if (scheduledJobs.get(i).getId() == jobInfo.getId()) {
return true;
}
}
return false;
}
}