簡體   English   中英

在 RxJava / RxAndroid 中更新有關進度的 UI 時發出單個項目

[英]Emit single item while update UI about progress in RxJava / RxAndroid

我目前正在嘗試在 Android 中學習 RxJava。 我需要一些指南。 目前,我正在嘗試將下面的 AsyncTask 重寫為 RxJava:

public class MyAsyncTask extends AsyncTask<Void, ProgressInfo, Result> {
    @Override
    protected Result doInBackground(Void... void) {
        //Long running task
        publishProgress(progressInfo);
        //Long running task
        return result;
    }
    @Override
    protected void onProgressUpdate(ProgressInfo... progressInfo) {
        //Update the progress to UI using data from ProgressInfo
    }
    @Override
    protected void onPostExecute(Result res) {
        //Task is completed with a Result
    }
}

在上面顯示的 AsyncTask 方法中,我可以通過使用onProgressUpdate方法更新有關進度的 UI,我將所需的每個數據打包到ProgressInfo中並在onProgressUpdate中反映 UI。 任務結束后, Result將從doInBackground傳遞到onPostExecute

但是,當我試圖用 RxJava 實現它時,我很難處理它。 由於我無法將任何參數傳遞給 Observer 中的onComplete 因此,我最終完成了以下實施。 我將ProgressInfoResult的傳遞合並到onNext中。

 Observable.create(emitter -> {
                //Long running task
                emitter.onNext(progressInfo);
                //Long running task
                emitter.onNext(result);
            }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object -> {
                    if(object instanceof ProgressInfo){
                        //Update the progress to UI using data from ProgressInfo
                    }else if(object instanceof Result){
                        //Task is completed with a Result
                    }
                });

問題 1:我在 RxJava 中的實現/概念是對還是錯?

雖然它有效,但我個人覺得上面的實現對我來說很奇怪和錯誤。 由於任務最終只是嘗試進行一些計算並得出一個單一的項目 - Result ProgressInfo的發射就像一個“側面”的東西,而不是“主要”的東西。 我應該用 Single.create() 來實現它。 但是如果我這樣做了,我想不出任何方法可以將任何ProgressInfo傳遞給我的 UI。

問題 2:在更新 UI 的過程中,是否有更好的想法/方式來發出單個項目?

如果是,你將如何在 RxJava 中實現這個邏輯? 你能告訴我你的代碼/例子嗎?

問題 1:我在 RxJava 中的實現/概念是對還是錯?

當然,這取決於您的用例。 如果您想對每個進度步驟提供反饋,據我所知,沒有辦法以不同的方式進行。 當任務需要相當長的時間並且您能夠提供有意義的進度信息時,我會建議提供進度反饋。

在一種類型中使用 ProgressInfo 和 Result 的並集並測試 null 或使用從 ProgressInfo 和 Result 繼承的標記接口。

interface ResultT { }

final class ProgressInfo implements ResultT { }

final class Result implements ResultT { }

當結果通過 onNext 發出時,我會建議完成 observable,以便通知訂閱者任務已經完成。 訂閱者將通過 onNext 和之后的 onComplete 接收結果。

Observable.<ResultT>create(emitter -> {
        emitter.onNext(progressInfo);
        emitter.onNext(result);

        emitter.onComplete();
    }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object -> {
                if (object instanceof ProgressInfo) {
                    //Update the progress to UI using data from ProgressInfo
                } else if (object instanceof Result) {
                    //Task is completed with a Result
                }
            });

如果您沒有有意義的進度信息,我建議您使用 Single。

問題 2:在更新 UI 的過程中,是否有更好的想法/方式來發出單個項目?

可以使用 doOn*-Operators 在訂閱和終止時更新 UI。 這種方式是最簡單的方式之一,但當來自其他訂閱的事件與 UI 更改交錯時可能會導致問題^1

.doOnSubscribe(disposable -> {/* update ui */})
            .subscribe(s -> {
                        // success: update ui
                    },
                    throwable -> {
                        // error happened: update ui
                    },
                    () -> {
                        // complete: update ui
                    });

我的建議是通過 class 和訂閱方法中的 switch-case 對所有狀態(例如成功/錯誤)進行建模(參見 ^1)。 首先發出一個 StartProgress 事件,然后是 ProgressInformation 事件,然后完成 SucessResult。 使用 onError*-operators 捕獲任何錯誤並返回 FailureResult,其中包含錯誤消息和可能的 throwable。

Observable.<ResultT>create(emitter -> {
        emitter.onNext(progressInfo);
        emitter.onNext(result);

        emitter.onComplete();
    }).startWith(new StartProgress())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .onErrorReturn(throwable -> new FailureResult(throwable))
            .subscribe(object -> {
                // when StartProgress -> updateUI
                // when ProgressInformation -> updateUI
                // ...
            });

^1 http://hannesdorfmann.com/android/mosby3-mvi-1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM