Migracja z GCMNetworkManager do WorkManager

Ten dokument wyjaśnia, jak przenieść aplikacje, aby używać biblioteki klienta WorkManager do wykonywania operacji w tle zamiast biblioteki GCMNetworkManager. Preferowanym sposobem planowania zadań w tle przez aplikację jest użycie zasobu WorkManager. Dzięki dołączeniu biblioteki WorkManager GCM możesz zezwolić WorkManagerowi na używanie GCM do planowania zadań na urządzeniach z Androidem z interfejsem API na poziomie 22 lub niższym.

Migracja do WorkManagera

Jeśli Twoja aplikacja używa obecnie GCMNetworkManager do wykonywania operacji w tle, wykonaj te czynności, aby przeprowadzić migrację do WorkManagera.

W podanych niżej krokach zakładamy, że zaczynasz od tego kodu GCMNetworkManagera, który definiuje i planuje Twoje zadanie:

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);

W tym przykładzie zakładamy, że MyUploadService definiuje rzeczywistą operację przesyłania:

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;
    }
}

Dołącz biblioteki WorkManagera

Aby używać klas WorkManager, musisz dodać bibliotekę WorkManager do zależności kompilacji. Musisz też dodać bibliotekę WorkManager GCM, która umożliwi usłudze WorkManager używanie GCM do planowania zadań, gdy Twoja aplikacja działa na urządzeniach, które nie obsługują JobScheduler (czyli na urządzeniach z interfejsem API na poziomie 22 lub niższym). Szczegółowe informacje o dodawaniu bibliotek znajdziesz w artykule Pierwsze kroki z usługą WorkManager.

Modyfikowanie pliku manifestu

Podczas implementacji usługi GCMNetworkManager dodano do pliku manifestu aplikacji wystąpienie GcmTaskService zgodnie z opisem w GcmNetworkManager dokumentacji referencyjnej. GcmTaskService sprawdza przychodzące zadanie i przekazuje je do modułu obsługi zadań. WorkManager zarządza przekazywaniem zadań do instancji roboczej, dzięki czemu nie potrzebujesz już klasy, która to robi. Wystarczy usunąć GcmTaskService z pliku manifestu.

Zdefiniuj instancję roboczą

Twoja implementacja GCMNetworkManager określa element OneoffTask lub RecurringTask, który określa, co należy zrobić. Musisz przepisać go jako Worker, zgodnie z opisem w sekcji Definiowanie próśb o pracę.

Przykładowy kod GCMNetworkManager definiuje zadanie myTask. Odpowiednik w usłudze WorkManager wygląda tak:

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()
    }
}

Istnieją pewne różnice między zadaniem GCM a funkcją Worker:

  • GCM przekazuje parametry do zadania za pomocą obiektu TaskParams. WorkManager używa danych wejściowych, które możesz określić w elemencie WorkRequest zgodnie z opisem w dokumentacji WorkManager dotyczącej definiowania danych wejściowych i wyjściowych w zadaniu. W obu przypadkach możesz przekazywać pary klucz-wartość określające wszelkie trwałe parametry wymagane przez zadanie.
  • GcmTaskService informuje o powodzeniu lub niepowodzeniu, zwracając flagi takie jak GcmNetworkManager.RESULT_SUCCESS. Element WorkManager Worker sygnalizuje swoje wyniki za pomocą metody ListenableWorker.Result, takiej jak ListenableWorker.Result.success(), i zwraca wartość zwracanej przez tę metodę.
  • Jak wspomnieliśmy, ograniczeń ani tagów nie określa się podczas definiowania obiektu Worker. Zamiast tego możesz to zrobić w następnym kroku, podczas tworzenia obiektu WorkRequest.

Zaplanuj przesłanie prośby o pracę

Zdefiniowanie Worker określa, co musisz zrobić. Aby określić, kiedy zadanie ma zostać wykonane, musisz zdefiniować właściwość WorkRequest:

  1. Utwórz obiekt OneTimeWorkRequest lub PeriodicWorkRequest, ustaw w razie potrzeby ograniczenia określające czas wykonywania zadania oraz tagi, które pozwolą Ci rozpoznać jego pracę.
  2. Przekaż żądanie do WorkManager.enqueue(), aby umieścić zadanie w kolejce do wykonania.

Na przykład w poprzedniej sekcji pokazaliśmy, jak przekonwertować OneoffTask na odpowiednik Worker. Ten tag Worker nie zawierał jednak ograniczeń wykonania i tagu obiektu OneoffTask. Zamiast tego podczas tworzenia obiektu WorkRequest ustawiamy ograniczenia i identyfikatory zadania. Zaznaczymy też, że zadanie nie może działać, jeśli nie ma połączenia sieciowego. Nie musisz wyraźnie prosić o połączenie sieciowe z GCMNetworkManager, ponieważ GCMNetworkManager domyślnie wymaga połączenia sieciowego, ale WorkManager nie wymaga połączenia sieciowego, chyba że dodasz konkretne ograniczenie. Po zdefiniowaniu obiektu WorkRequest zostaje on dodany do kolejki w usłudze 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);

Mapowania interfejsów API

W tej sekcji omawiamy, jak niektóre funkcje i ograniczenia GCMNetworkManager są mapowane na odpowiedniki w usłudze WorkManager.

Mapowania ograniczeń

GCMNetworkManager pozwala określić szereg ograniczeń związanych z czasem uruchamiania zadania. W większości przypadków występuje jednoznaczne ograniczenie WorkManagera. W tej sekcji są wymienione odpowiedniki.

Ustaw ograniczenia dotyczące zadań GCMNetworkManager, wywołując odpowiednią metodę w obiekcie Builder w zadaniu. Możesz na przykład ustawić wymaganie dotyczące sieci, wywołując metodę Task.Builder.setRequiredNetwork().

W usłudze WorkManager tworzysz obiekt Constraints.Builder i wywołujesz jego metody, aby ustawić ograniczenia (np. Constraints.Builder.setRequiredNetworkType())), a następnie za pomocą narzędzia budowniczego tworzysz obiekt ograniczeń, który możesz dołączyć do zadania. Więcej informacji znajdziesz w artykule na temat definiowania próśb o pracę.

Ograniczenie GCMNetworkManager Odpowiednik WorkManager Uwagi
setPersisted() (niewymagane) Wszystkie zadania WorkManager są zachowywane po ponownym uruchomieniu urządzenia
setRequiredNetwork() setRequiredNetworkType() Domyślnie GCMNetworkManager wymaga dostępu do sieci. WorkManager domyślnie nie wymaga dostępu do sieci. Jeśli Twoje zadanie wymaga dostępu do sieci, musisz użyć sieci setRequiredNetworkType(CONNECTED) lub ustawić bardziej konkretny typ sieci.
setRequiresCharging()

Inne mapowania

Oprócz ograniczeń do zadań GCMNetworkManager możesz stosować też inne ustawienia. W tej sekcji znajdziesz informacje o sposobach stosowania tych ustawień do zadania WorkManager.

tagi.

Wszystkie zadania GCMNetworkManager muszą zawierać ciąg tagu, który ustawia się, wywołując metodę setTag() konstruktora. Zadania WorkManager są jednoznacznie identyfikowane przez identyfikator, który jest automatycznie generowany przez usługę WorkManager. Aby uzyskać ten identyfikator, wywołaj WorkRequest.getId(). Dodatkowo żądania robocze mogą opcjonalnie zawierać 1 lub więcej tagów. Aby ustawić tag dla zadania WorkManager, wywołaj metodę WorkRequest.Builder.addTag(), zanim utworzysz za pomocą tego konstruktora WorkRequest.

W GCMNetworkManager możesz wywołać metodę setUpdateCurrent(), aby określić, czy zadanie ma zastąpić którekolwiek istniejące zadanie tym samym tagiem. równoważne podejściem WorkManager jest dodanie zadania do kolejki przez wywołanie enqueueUniqueWork() lub enqueueUniquePeriodicWork(). Jeśli używasz tych metod, nadajesz zadaniu unikalną nazwę, a także określasz, jak WorkManager ma je obsługiwać, jeśli istnieje już oczekujące zadanie o tej nazwie. Więcej informacji znajdziesz w artykule o obsłudze unikalnych zadań.

Parametry zadania

Parametry możesz przekazywać do zadania GCMNetworkManager, wywołując metodę Task.Builder.setExtras() i przekazując Bundle z parametrami. WorkManager umożliwia przekazanie do zadania WorkManager obiektu Data zawierającego parametry jako pary klucz-wartość. Więcej informacji znajdziesz w artykule Przypisywanie danych wejściowych.