Synchrone oder Asynchrone Rxjava innerhalb der Arbeiter (von WorkManager-Komponente), was die richtige Wahl ist?

Ich bin neu an der neuen Architektur Komponente WorkManager, ich mein API-Aufrufe über Retrofit und RxJava.

Mein use-case ist hier, um neue Beiträge aus dem Backend, dann zeigen Sie die Benachrichtigung, und aktualisieren Sie ein widget.

Also den code in doWork () – Methode aus der Arbeiter-Klasse, kann etwas Aussehen wie diese.

@NonNull
  @Override
  public Result doWork() {
    AppDependencies appDependencies = new AppDependencies((Application) getApplicationContext());
    Repository repository = appDependencies.getRepository();

    repository.getNewPosts()
        .flatMap(newPosts -> repository.inserPosts(newPosts).toObservable())
        .doOnError(Timber::e)
        //if success - > return  Result.SUCCESS,
        //-> show notification
        //-> update widget
        //error-> return Result.Failure
        .dontKnowWhatBestNextThing; //blocking or subscribing

    //if we reached here then Retry
    return Result.RETRY;
  }

Meine Frage ist, was ist der richtige Weg, um eine RxJava code innerhalb der Arbeiter-Klasse, weil der doWork () – Methode hat einen Rückgabewert, also muss ich machen, Rx-code Synchron.

wenn ich mit der nicht blockierenden Rx-Ansatz, wie kann ich den return-Wert (Erfolg – Misserfolg – Retry)

  • Innerhalb des lambda -, können wir natürlich wieder zu den beiden Status – Erfolg, Scheitern, oder Wiederholen Sie nur sicherstellen, dass die gleichen Zeile in der letzten Zeile bei der Ausführung.
  • könnten Sie bitte machen Sie mehr klar mit dem code
  • verwenden von lambda mit offenen Klammern innerhalb onError oder onSuccess und da wir wissen, dass jeder Bedingung funktioniert und wahrscheinlich der Letzte in der Verkettung, in Klammern Ihre Arbeit machen und in der letzten Zeile zurück, die den entsprechenden status zu WorkManager
  • ‚Ergebnis zurückgeben.WIEDERHOLEN “ am Ende ist okay und sollte erreichen nur in seltenen Fällen. Meist würden Sie wollen, zu geben den status von innen.
  • BTW, den Erhalt einer Referenz auf die Application durch Gießen der Anwendungskontext ist nicht garantiert, um zu arbeiten. Ich habe meistens gesehen, dass es nicht in Emulatoren, aber auch sehr selten auf echten Geräten. Es ist sicherer, legen Sie ein statisches Feld in der Anwendung onCreate und geben Sie einen statischen getter.
  • kannst du die Letzte Folge mit uns, ich bin verloren und ich brauche einige Tipps

 

4 Replies
  1. 27

    Seit WorkManager version 1.0.0-alpha12 Sie ein neues Artefakt, genannt work-rxjava2 enthält RxWorker Klasse für genau diesen Zweck. Es ist ein besonderer Fall von ListenableWorker erwartet Single<Result>.

    Es zu implementieren, stellen Sie zunächst sicher, dass Sie korrekte Artefakte zu Ihrem build.gradle:

    dependencies {
       ...
       implementation "android.arch.work:work-runtime-ktx:1.0.0-beta01"
       implementation "android.arch.work:work-rxjava2:1.0.0-beta01"
    }

    Und Umsetzung Ihrer RxWorker:

    class MyRxWorker(context : Context, params : WorkerParameters) : RxWorker(context, params) {
    
        val remoteService = RemoteService()
    
        override fun createWork(): Single<Result> {
            return remoteService.getMySingleResponse()
                    .doOnSuccess { /* process result somehow */ }
                    .map { Result.success() }
                    .onErrorReturn { Result.failure() }
        }
    }
    • Was der RemoteService ist ? Können Sie erklären, mehr details, bitte ? Weil ich stecken mit diesem Problem für ein paar Tage
  2. 6

    Edit: WorkManager nun offiziell unterstützt RxWorker. Werfen Sie einen Blick auf die Antwort oben für mehr Informationen.

    doWork geschieht auf einem hintergrund-thread. Also ist es sicher zu blockieren. Sie sollten warten, bis die Observable abgeschlossen ist, bevor Sie Sie wieder ein Result.

    Wir sind auch dabei, diese leichter mit asynchronen APIs. Bleiben Sie dran.

  3. 1

    Ja, machen den Rx-code synchron. Die Dokumentation für doWork ist minimal, aber die Beschreibung

    Diese Methode überschreiben, um Ihre eigentliche Hintergrundverarbeitung.

    impliziert, dass es erwartet, oder zumindest blockieren. Und natürlich, Sie können nicht wissen, was doWork zurückkehren sollte, bis das Netzwerk die Anfrage geklärt wurde.

  4. 0

    Fand ich die Lösung.
    Sie verwenden sollten, RxWorker oder SettableFuture für async-Jobs

    Dies ist meine Lösung für die immer aktuellen Lage. Arbeiten wie ein Charme

    class LocationWorker(context: Context, private val workerParams: WorkerParameters) :
    ListenableWorker(context, workerParams) {
    
    lateinit var mFuture: SettableFuture<ListenableWorker.Result>
    private var fusedLocationProviderClient = FusedLocationProviderClient(context)
    
    @SuppressLint("RestrictedApi", "MissingPermission")
    override fun startWork(): ListenableFuture<Result> {
        val uniqueId = workerParams.inputData.getString(UNIQUE_ID_KEY)
        mFuture = SettableFuture.create()
        Timber.d("mFutureStart")
        fusedLocationProviderClient.lastLocation.addOnSuccessListener { location ->
            Timber.d("location == $location")
            if (location != null) {
                mFuture.set(Result.success())
            } else mFuture.set(Result.failure())
          }
        return mFuture
       }
    }

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.