为什么我在 View Model 中的 observable 仅在第二次调用后才发出值

问题描述

我有 observable 的奇怪行为。 我从 viewmodel getData() 中的 SecondFragment void 调用它应该每秒发出值,但它没有。在日志中我只有:

getData called.
getData subscribe

当我返回上一个片段时(viewmodelFragment 被销毁(丢弃的一次性物品))并再次进入它应该像它应该的那样工作。同样,当我第二次通过按钮调用方法时。

有人知道为什么它不能正常工作吗?

BaseFragmentCompat

public abstract class PreferenceFragmentCompatBase extends PreferenceFragmentCompat {
    private static final String TAG = "PreferenceFragmentCompa";

    private final Compositedisposable mCompositedisposable = new Compositedisposable();

    public void addCompositedisposable(disposable disposable) {
        mCompositedisposable.add(disposable);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mCompositedisposable.dispose();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mCompositedisposable.clear();
    }

    public disposableObserver<String> preferenceSubscriber(Preference preference) {
        return new disposableObserver<String>() {
            @Override
            public void onNext(@NonNull String s) {
                if (preference == null)
                    return;
                preference.setSummary(s);
            }

            @Override
            public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
                if (preference == null)
                    return;
                preference.setSummary(NO_DATA);
            }

            @Override
            public void onComplete() {
                Log.d(TAG,"onComplete: onComplete");
            }

            @Override
            protected void onStart() {
                if (preference == null)
                    return;
                preference.setSummary("Ładowanie...");
            }
        };
    }

    protected NavBackStackEntry navGraphviewmodels(int navigation) {
        return NavHostFragment.findNavController(this).getBackStackEntry(navigation);
    }
}

第二个片段

public class SecondFragment extends PreferenceFragmentCompatBase {
    private static final String TAG = "SettingsDataiCzasFragme";

    private SettingsDataiCzasviewmodel mviewmodel;
    private NavController navController;

    public SettingsDataiCzasFragment() {
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState,String rootKey) {
        addPreferencesFromresource(R.xml.settings_dataiczas);
        mviewmodel = new viewmodelProvider(navGraphviewmodels(R.id.navigation_data_i_czas)).get(SettingsDataiCzasviewmodel.class);
        navController = NavHostFragment.findNavController(this);

        observeData();
        mviewmodel.getData(); // here I called void in viewmodel but nothing happends
    }

    private void observeData() {
        final Preference dateTime = findPreference(Constants.date_time_cash);

        addCompositedisposable(
                mviewmodel.getDateAndTime()
                        .doOnSubscribe(disposable -> Log.d(TAG,"observeData: subscribe."))
                        .doOnTerminate(() -> Log.d(TAG,"observeData: terminate"))
                        .doOndispose(() -> Log.d(TAG,"observeData: disposed"))
                        .subscribeOn(Schedulers.io())
                        .observeOn(Schedulers.io())
                        .map(zoneddatetimeStr -> FormatHelper.convertInstanttoSimpleDate(zoneddatetimeStr,true,true))
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribeWith(preferenceSubscriber(dateTime))
        );
    }

    @Override
    public boolean onPreferenceTreeClick(Preference preference) {
        .....
}

基础视图模型

public abstract class SettingsAbstractviewmodel extends Androidviewmodel {
    private static final String TAG = "SettingsServerAbstractV";

    public static final String NO_DATA = "Brak danych";

    private final Compositedisposable mCompositedisposable;


    public SettingsAbstractviewmodel(@NonNull Application application) {
        super(application);
        mCompositedisposable = new Compositedisposable();
    }

    /**
     * Funkcja pobierająca dane z różnych źródeł przy utworzeniu viewmodelu
     */
    public abstract void getData();

    public void addCompositedisposable(disposable disposable) {
        mCompositedisposable.add(disposable);
    }

    @Override
    public void onCleared() {
        super.onCleared();
        Log.i(TAG,"onCleared: called for: " + this);
        Log.i(TAG,"onCleared: disposable: " + mCompositedisposable);
        mCompositedisposable.clear();

    }
}

视图模型

public class viewmodeL extends SettingsAbstractviewmodel {
    private static final String TAG = "SettingsDataiCzasviewmodel";

    private TimeRepository mTimeRepository;
    private int[] zoneOffsets;
    private String[] zoneNames;
    private BehaviorSubject<zoneddatetime> dateAndTime;
    public PublishSubjectDataRx3<zoneddatetime> syncTimeResult;
    private disposable getTimedisposable;
    private disposable subscribe;
    public SettingsDataiCzasviewmodel(@NonNull Application application) {
        super(application);
        mTimeRepository = new TimeRepository(getApplication());
        dateAndTime = BehaviorSubject.create();
        syncTimeResult = new PublishSubjectDataRx3<>();
    }

    @Override
    public void getData() {
        Log.d(TAG,"getData: called.");
        if (subscribe != null)
            subscribe.dispose();
        subscribe = Observable.interval(0,1000,TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.computation())
                .doonSubscribe(ignore -> Log.d(TAG,"getData: subscribe))
                .doondispose(() -> Log.d(TAG,"getData: dispose))
                .switchMapSingle(ignore ->
                        mTimeRepository.getZonedTime()
                                .subscribeOn(Schedulers.io())
                                .subscribeOn(Schedulers.io())
                                .observeOn(Schedulers.io()))
                .subscribe(
                        zoneddatetimeStr -> {
                            dateAndTime.onNext(zoneddatetimeStr);
                        },e -> Log.e(TAG,"getData: ",e)
                );
    }

    @Override
    public void onCleared() {
        super.onCleared();
        if (subscribe != null)
            subscribe.dispose();
    }

    public void downloadTimeFromServer(int zoneOffset) {
        Log.d(TAG,"downloadTimeFromServer: called.");
        syncTimeResult.loading();
        getTimedisposable = mTimeRepository.getDateAndTimeFromServer()
                .subscribeOn(Schedulers.io())
                .doOnEvent((aLong,throwable) -> Log.d(TAG,"downloadTimeFromServer: " + aLong + throwable))
                .flatMapCompletable(aLong -> mTimeRepository.setDateAndTimeFromUtc(aLong,zoneOffset))
                .doOnEvent(throwable -> Log.d(TAG,"downloadTimeFromServer: " + throwable))
                .andThen(Single.defer(() -> mTimeRepository.getZonedTime()))
                .doOnEvent((zoneddatetime,"downloadTimeFromServer: " + zoneddatetime.toString() + throwable))
                .observeOn(Schedulers.io())
                .subscribe(
                        zoneddatetime -> {
                            syncTimeResult.success(zoneddatetime);
                        },e -> {
                            Logs.e(TAG,"getTimeFromServer: ",e);
                            String errorMsg;
                            if (e instanceof UnkNownHostException)
                                errorMsg = "Wystąpił błąd podczas próby komunikacji z serwerem.\nsprawdź połączenie z internetem.";
                            else
                                errorMsg = e.getMessage();
                            syncTimeResult.error(errorMsg);
                        }
                );
        addCompositedisposable(getTimedisposable);
    }

    public Observable<Resource<zoneddatetime>> getSyncTimeResult() {
        return syncTimeResult.getorigin();
    }

    public Observable<zoneddatetime> getDateAndTime() {
        return dateAndTime;
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)