Migrer GCMNetworkManager vers WorkManager

Ce document explique comment migrer des applications afin d'utiliser la bibliothèque cliente WorkManager plutôt que la bibliothèque GCMNetworkManager pour effectuer des opérations en arrière-plan. Nous vous recommandons d'utiliser WorkManager pour planifier des tâches en arrière-plan. En incluant également la bibliothèque GCM WorkManager, vous pouvez permettre à WorkManager d'utiliser GCM pour planifier les tâches sur des appareils Android exécutant le niveau d'API 22 ou inférieur.

Migrer vers WorkManager

Si votre application utilise actuellement GCMNetworkManager pour effectuer des opérations en arrière-plan, procédez comme suit pour migrer vers WorkManager.

Pour les étapes suivantes, nous partons du principe que vous commencez avec le code GCMNetworkManager suivant, qui définit et planifie votre tâche :

Kotlin

val myTask = OneoffTask.Builder()
    // setService() says what class does the work
    .setService(MyUploadService::class.java)
    // Don't run the task unless device is charging
    .setRequiresCharging(true)
    // Run the task between 5 & 15 minutes from now
    .setExecutionWindow(5 * DateUtil.MINUTE_IN_SECONDS,
            15 * DateUtil.MINUTE_IN_SECONDS)
    // Define a unique tag for the task
    .setTag("test-upload")
    // ...finally, build the task and assign its value to myTask
    .build()
GcmNetworkManager.getInstance(this).schedule(myTask)

Java

// In GcmNetworkManager, this call defines the task and its
// runtime constraints:
OneoffTask myTask = new OneoffTask.Builder()
    // setService() says what class does the work
    .setService(MyUploadService.class)
    // Don't run the task unless device is charging
    .setRequiresCharging(true)
    // Run the task between 5 & 15 minutes from now
    .setExecutionWindow(
        5 * DateUtil.MINUTE_IN_SECONDS,
        15 * DateUtil.MINUTE_IN_SECONDS)
    // Define a unique tag for the task
    .setTag("test-upload")
    // ...finally, build the task and assign its value to myTask
    .build();
GcmNetworkManager.getInstance(this).schedule(myTask);

Dans cet exemple, nous supposons que MyUploadService définit l'opération d'importation réelle :

Kotlin

class MyUploadService : GcmTaskService() {
    fun onRunTask(params: TaskParams): Int {
        // Do some upload work
        return GcmNetworkManager.RESULT_SUCCESS
    }
}

Java

class MyUploadService extends GcmTaskService {
    @Override
    public int onRunTask(TaskParams params) {
        // Do some upload work
        return GcmNetworkManager.RESULT_SUCCESS;
    }
}

Inclure les bibliothèques WorkManager

Pour utiliser les classes WorkManager, vous devez ajouter la bibliothèque WorkManager à vos dépendances de compilation. Vous devez également ajouter la bibliothèque GCM WorkManager, qui permet à WorkManager d'utiliser GCM pour la planification des tâches lorsque votre application est exécutée sur des appareils non compatibles avec JobScheduler (c'est-à-dire des appareils exécutant le niveau d'API 22 ou un niveau inférieur). Pour en savoir plus sur l'ajout de bibliothèques, consultez la page Premiers pas avec WorkManager.

Modifier le fichier manifeste

Lorsque vous avez implémenté GCMNetworkManager, vous avez ajouté une instance de GcmTaskService au fichier manifeste de votre application, comme décrit dans la documentation de référence de GcmNetworkManager. GcmTaskService examine la tâche entrante et la délègue au gestionnaire de tâches. Étant donné que WorkManager gère la délégation des tâches à votre nœud de calcul (Worker), vous n'avez plus besoin d'une classe pour effectuer cette opération. Il vous suffit de supprimer votre GcmTaskService du fichier manifeste.

Définir le nœud de calcul

Votre implémentation de GCMNetworkManager définit une OneoffTask ou une RecurringTask, qui spécifie précisément le travail à effectuer. Vous devez la remplacer par Worker, comme indiqué dans la section Définir vos requêtes de travail.

L'exemple de code GCMNetworkManager définit une tâche myTask. Voici l'équivalent WorkManager :

Kotlin

class UploadWorker(context: Context, params: WorkerParameters)
                        : Worker(context, params) {
    override fun doWork() : Result {
        // Do the upload operation ...
        myUploadOperation()

        // Indicate whether the task finished successfully with the Result
        return Result.success()
    }
}

Java

public class UploadWorker extends Worker {

    public UploadWorker(
        @NonNull Context context,
        @NonNull WorkerParameters params) {
        super(context, params);
    }

    @Override
    public Result doWork() {
      // Do the upload operation ...

      myUploadOperation()

      // Indicate whether the task finished successfully with the Result
      return Result.success()
    }
}

Il existe quelques différences entre la tâche GCM et Worker :

  • GCM utilise un objet TaskParams pour transmettre des paramètres à la tâche. WorkManager utilise des données d'entrée que vous pouvez spécifier dans la WorkRequest, tel que décrit dans la documentation WorkManager expliquant comment Définir les entrées/sorties pour vos tâches. Dans les deux cas, vous pouvez transmettre des paires clé/valeur en spécifiant tous les paramètres persistants nécessaires à la tâche.
  • GcmTaskService indique la réussite ou l'échec en renvoyant des indicateurs tels que GcmNetworkManager.RESULT_SUCCESS. Un Worker WorkManager signale ses résultats à l'aide d'une méthode ListenableWorker.Result, telle que ListenableWorker.Result.success(), et en renvoyant la valeur renvoyée par cette méthode.
  • Comme indiqué précédemment, vous ne définissez pas les contraintes ni les balises lorsque vous définissez Worker, mais à l'étape suivante, lorsque vous créez WorkRequest.

Programmer une requête de travail

La définition d'un Worker spécifie les actions à effectuer. Pour indiquer le moment où le travail doit être effectué, vous devez définir l'élément WorkRequest :

  1. Créez une OneTimeWorkRequest ou une PeriodicWorkRequest, puis définissez les contraintes souhaitées indiquant le délai d'exécution de la tâche, ainsi que toutes les balises permettant d'identifier votre travail.
  2. Transmettez la requête à WorkManager.enqueue() afin que la tâche soit mise en file d'attente pour son exécution.

Dans la section précédente, nous avons indiqué comment convertir une OneoffTask en un Worker équivalent. Cependant, ce Worker ne contient pas les contraintes et la balise d'exécution de l'objet OneoffTask. À la place, nous définissons les contraintes et l'identifiant de tâche lorsque nous créons la WorkRequest. Nous devons également indiquer que la tâche ne doit pas être exécutée à moins qu'une connexion réseau ne soit disponible. Vous n'avez pas besoin de demander explicitement une connexion réseau avec GCMNetworkManager, car il nécessite une connexion réseau par défaut. WorkManager n'exige pas de connexion réseau, sauf si vous ajoutez spécifiquement cette contrainte. Une fois la WorkRequest définie, nous la plaçons dans la file d'attente avec WorkManager.

Kotlin

val uploadConstraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresCharging(true).build()

val uploadTask = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(uploadConstraints)
    .build()
WorkManager.getInstance().enqueue(uploadTask)

Java

Constraints uploadConstraints = new Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresCharging(true)
    .build();

OneTimeWorkRequest uploadTask =
        new OneTimeWorkRequest.Builder(UploadWorker.class)
  .setConstraints(uploadConstraints)
  .build();
WorkManager.getInstance().enqueue(uploadTask);

Mappages d'API

Cette section explique la correspondance entre certaines fonctionnalités et contraintes GCMNetworkManager et leurs équivalents WorkManager.

Mappages de contraintes

GCMNetworkManager vous permet de définir un certain nombre de contraintes pour l'exécution de votre tâche. Dans la plupart des cas, il existe une contrainte WorkManager équivalente claire. Cette section présente ces équivalents.

Définissez des contraintes sur les tâches GCMNetworkManager en appelant la méthode appropriée dans l'objet du compilateur de la tâche. Par exemple, vous pouvez définir une configuration réseau requise en appelant Task.Builder.setRequiredNetwork().

Dans WorkManager, vous créez un objet Constraints.Builder et appelez ses méthodes pour définir des contraintes (par exemple, Constraints.Builder.setRequiredNetworkType()), puis utilisez le compilateur pour créer un objet Contraintes que vous pouvez associer à la requête de travail. Pour en savoir plus, consultez la section Définir vos requêtes de travail.

Contrainte GCMNetworkManager Équivalent WorkManager Remarques
setPersisted() (facultatif) Toutes les tâches WorkManager sont conservées lors des redémarrages d'appareils
setRequiredNetwork() setRequiredNetworkType() Par défaut, GCMNetworkManager nécessite un accès réseau, contrairement à WorkManager. Si votre tâche nécessite un accès réseau, vous devez utiliser setRequiredNetworkType(CONNECTED) ou définir un type de réseau plus spécifique.
setRequiresCharging()

Autres mappages

Outre les contraintes, vous pouvez appliquer d'autres paramètres aux tâches GCMNetworkManager. Cette section indique comment appliquer ces paramètres à une tâche WorkManager.

Balises

Toutes les tâches GCMNetworkManager doivent comporter une chaîne de balises, que vous définissez en appelant la méthode setTag() du compilateur. Les tâches WorkManager présentent un identifiant unique, qui est automatiquement généré par WorkManager et que vous pouvez obtenir en appelant WorkRequest.getId(). En outre, les requêtes de travail peuvent comporter une ou plusieurs balises facultatives. Pour définir une balise pour votre tâche WorkManager, appelez la méthode WorkRequest.Builder.addTag() avant d'utiliser ce compilateur pour créer la WorkRequest.

Dans GCMNetworkManager, vous pouvez appeler setUpdateCurrent() pour indiquer si la tâche doit remplacer toute tâche existante portant la même balise. L'approche WorkManager équivalente consiste à placer la tâche en file d'attente en appelant enqueueUniqueWork() ou enqueueUniquePeriodicWork(). Si vous utilisez ces méthodes, donnez un nom unique à la tâche et indiquez comment WorkManager doit traiter la requête s'il y a déjà une tâche en attente portant ce nom. Pour en savoir plus, consultez la section Gérer un travail unique.

Paramètres de la tâche

Vous pouvez transmettre des paramètres à une tâche GCMNetworkManager en appelant Task.Builder.setExtras() et en transmettant un Bundle contenant les paramètres. WorkManager vous permet de transmettre un objet Data à la tâche WorkManager contenant les paramètres sous forme de paires clé/valeur. Pour en savoir plus, consultez Attribuer des données d'entrée.