Domanda

Sto cercando di aggiungere un osservatore RX al mio database SQLITE e sto sicuramente mancando qualcosa dalla mia implementazione in quanto né i metodi onNext() e onCompleted() dal mio osservatore non vengono chiamati.

Ecco il mio osservatore:

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

Questi sono i miei metodi LoaderCallback:

@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) {

    }
.

Il codice del contenuto dell'osservatore segue sotto:

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

Ho messo i registri ovunque nel mio codice e vengono stampati come dovrebbero, ad eccezione dei metodi onNext e onCompleted.Qualche idea ciò che potrei mancare dalla mia implementazione?

È stato utile?

Soluzione

Vedo alcuni problemi con il codice sopra.

1st: non stai effettivamente chiamando onnext / oncompleted ovunque. Dal momento che stai cercando di collegare i due paradigmi (Loader & RX), allora dovresti inserire il successivo in onloadFinited (con OnError nel caso in cui si desidera chiamare quando non ci sono dati, ma che chiuderà l'abbonamento) e acceso onloaderreset

2nd: stai rifissando l'abbonamento in onloadFinited, che non penso che vorresti - perché vorresti riscriverti ogni volta che hai nuovi dati? Dovresti farlo quando si crea il caricatore e annullare l'iscrizione quando si distrugge il caricatore (onloaderreset).

Questa è una possibile implementazione:

@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();
        }
    }
.

In mente che strutturato come questo, in caso di nessun dato chiuderà effettivamente l'abbonamento (OnError lo fa) in modo da non poter ricevere altri dati dal caricatore. Se non lo vuoi, allora in caso di OnError sopra, chiameresti effettivamente onnext con Null o New ArrayList e poi prenditi cura di esso nel tuo osservatore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top