Frage

Ich versuche, einen RX-Beobachter zu meiner SQLite-Datenbank hinzuzufügen, und mir fehlt sicherlich etwas in meiner Implementierung, da keiner der beiden onNext() Und onCompleted() Methoden meines Beobachters werden nicht aufgerufen.

Hier ist mein Beobachter:

private final Observer<List<Order>> mObjectiveObserver = new Observer<List<Order>>() {
        @Override
        public void onCompleted() {
            System.out.println("Load completed");
        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(List<Order> objectives) {
            System.out.println("On Next: " + objectives.size() + " elements found!");
            orderAdapter.clear();
            if (objectives != null) {
                orderAdapter.addAll(objectives);
                mCirclePulseView.setVisibility(View.INVISIBLE);
            } else {
                mCirclePulseView.setVisibility(View.VISIBLE);
            }
            orderAdapter.notifyDataSetChanged();
        }
    };

Das sind meine LoaderCallback Methoden:

@Override
    public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
        Loader<Cursor> loader = null;
        switch (loaderId) {
            case LOADER_ORDERS:
                System.out.println("Create loader called");
                loader = new CursorLoader(OrderManagerApplication.getAppContext(), OrderManagerContract.Order.CONTENT_URI,
                        QueryOrder.PROJECTION_SIMPLE, null, null, OrderManagerContract.Order.DATE_SORT);
                break;
        }
        return loader;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        if (getActivity() == null) {
            return;
        }

        if (data != null && !data.isClosed()) {
            System.out.println("Finished loading orders, data not null");
            switch (loader.getId()) {
                case LOADER_ORDERS:

                    if (subscription != null && !subscription.isUnsubscribed()) {
                        subscription.unsubscribe();
                    }

                    subscription = AndroidObservable
                            .bindFragment(this, DatabaseHelper.mainOrdersObservable(data))
                            .subscribeOn(Schedulers.computation())
                            .unsubscribeOn(AndroidSchedulers.mainThread())
                            .subscribe(mObjectiveObserver);
                    System.out.println("I should be here, onLoadFinished");
                    break;
            }
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {

    }

Der Inhaltsbeobachtercode folgt unten:

class HomeOrdersContentObserver extends ContentObserver {
        private int mLoaderId = 0;

        public HomeOrdersContentObserver(Handler handler, int loaderId) {
            super(handler);
            mLoaderId = loaderId;
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            if (getActivity() == null) {
                return;
            }

            Bundle bundle = new Bundle();
            //bundle.putString(FILTER_TXT, lastFilterQ);
            restartLoader(mLoaderId, bundle);
        }
    }

    public void restartLoader(int loaderId, Bundle args) {
        getLoaderManager().restartLoader(loaderId, args, this);
    }

Ich habe überall in meinem Code Protokolle eingefügt und sie werden bis auf diese Ausnahme so gedruckt, wie sie sollten onNext Und onCompleted Methoden.Irgendwelche Ideen, was mir in meiner Implementierung fehlen könnte?

War es hilfreich?

Lösung

Ich sehe ein paar Probleme mit dem obigen Code.

1:Sie rufen onNext/onCompleted nirgendwo auf.Da Sie versuchen, die beiden Paradigmen (Loader und Rx) zu verbinden, müssen Sie onNext in onLoadFinished (mit onError für den Fall, dass es aufgerufen werden soll, wenn keine Daten vorhanden sind, aber dadurch das Abonnement geschlossen wird) und onCompleted in einfügen onLoaderReset

2.:Sie wiederholen das Abonnement in onLoadFinished, was Sie meiner Meinung nach nicht möchten. Warum sollten Sie sich jedes Mal erneut anmelden, wenn Sie neue Daten haben?Sie sollten dies tun, wenn Sie den Loader erstellen, und sich abmelden, wenn Sie den Loader zerstören (onLoaderReset).

Dies ist eine mögliche Implementierung:

@Override
    public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
        Loader<Cursor> loader = null;
        switch (loaderId) {
            case LOADER_ORDERS:
                System.out.println("Create loader called");
                loader = new CursorLoader(OrderManagerApplication.getAppContext(), OrderManagerContract.Order.CONTENT_URI,
                        QueryOrder.PROJECTION_SIMPLE, null, null, OrderManagerContract.Order.DATE_SORT);

                if (subscription != null && !subscription.isUnsubscribed()) {
                    subscription.unsubscribe();
                }

                subscription = AndroidObservable
                        .bindFragment(this, DatabaseHelper.mainOrdersObservable(data))
                        .subscribeOn(Schedulers.computation())
                        .unsubscribeOn(AndroidSchedulers.mainThread())
                        .subscribe(mObjectiveObserver);
                break;
        }
        return loader;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        if (getActivity() == null) {
            return;
        }

        if (data != null && !data.isClosed()) {
            System.out.println("Finished loading orders, data not null");
            switch (loader.getId()) {
                case LOADER_ORDERS:
                    mObjectiveObserver.onNext(data);
                    System.out.println("I should be here, onLoadFinished");
                    break;
            }
        } else {
            mObjectiveObserver.onError("No data available");
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        if (subscription != null && !subscription.isUnsubscribed()) {
            subscription.unsubscribe();
        }
    }

Beachten Sie, dass bei einer solchen Struktur das Abonnement tatsächlich geschlossen wird, wenn keine Daten vorhanden sind (onError macht das), sodass Sie keine weiteren Daten vom Loader empfangen können.Wenn Sie das nicht möchten, würden Sie im Falle von onError oben tatsächlich onNext mit null oder new ArrayList aufrufen und sich dann in Ihrem Beobachter darum kümmern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top