Question

J'essaie d'ajouter un observateur RX à ma base de données SQLite et il me manque sûrement quelque chose dans mon implémentation car ni l'un ni l'autre. onNext() et onCompleted() les méthodes de mon observateur ne sont pas appelées.

Voici mon observateur :

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

Ce sont mes LoaderCallback méthodes :

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

    }

Le code de l'observateur de contenu suit ci-dessous :

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

J'ai mis des journaux partout dans mon code et ils sont imprimés comme ils le devraient, à l'exception de ceci onNext et onCompleted méthodes.Avez-vous des idées sur ce qui pourrait me manquer dans ma mise en œuvre ?

Était-ce utile?

La solution

Je vois quelques problèmes avec le code ci-dessus.

1er :vous n'appelez pas réellement onNext/onCompleted nulle part.Puisque vous essayez de connecter les deux paradigmes (Loader & Rx), vous devrez alors mettre onNext dans onLoadFinished (avec onError au cas où vous voudriez qu'il soit appelé alors qu'il n'y a pas de données, mais cela fermera l'abonnement) et onCompleted dans onLoaderReset

2ème :vous refaites l'abonnement dans onLoadFinished, ce que je ne pense pas que vous voudriez - pourquoi voudriez-vous vous réabonner à chaque fois que vous avez de nouvelles données ?Vous devez le faire lors de la création du chargeur et vous désinscrire lors de la destruction du chargeur (onLoaderReset).

Voici une implémentation possible :

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

Gardez à l'esprit que structuré comme ceci, en cas d'absence de données, l'abonnement sera clôturé (onError le fait), vous ne pourrez donc plus recevoir de données du chargeur.Si vous ne le souhaitez pas, alors en cas de onError ci-dessus, vous appelleriez en fait onNext avec null ou new ArrayList, puis vous en occuperiez dans votre observateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top