RXJava передает значение в onComplete

Я использую RXJava 2. После некоторой логики в методе subscribe я хочу удалить используемый файл. Думаю, мне следует сделать это в onComplete. Но я не могу передать туда свой объект File. Мой код: Вопросы:

Observer<Bitmap> observer = new Observer<Bitmap>() {
    @Override
    public void onSubscribe(Disposable d) {
    }

    @Override
    public void onNext(Bitmap bitmap) {
        if(mImageView.getTag().toString().equals(TAG)) {
            mImageView.setImageBitmap(bitmap);
        }
    }

    @Override
    public void onError(Throwable e) {
    }

    @Override
    public void onComplete() {
        //            outputFile.delete();
    }
};

Observable<Bitmap> observable = Observable.create(new ObservableOnSubscribe<Bitmap>() {
    @Override
    public void subscribe(ObservableEmitter<Bitmap> e) throws Exception {
        File outputFile = new File(newTAG);
        // do some stuff with a file
        Bitmap bitmap = decodeSampledBitmapFromUrl(newTAG, width, height);
        e.onNext(bitmap);
        // now I need to delete a file
        e.onComplete();
        }
    }
);
observable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
  1. Как передать outputFile в onComplete?
  2. Есть ли способ создать наблюдаемое и подписаться на него в одном событии или в меньшем количестве кода?

person Rainmaker    schedule 07.04.2017    source источник
comment
1) используйте типы кортежей и сохраните файл в своем наблюдателе. 2) вы можете разделить общий код на методы, но в противном случае у вас всегда будет 1 экземпляр, созданный для Observable и 1 для Observer.   -  person akarnokd    schedule 07.04.2017
comment
Если я удалю свой файл внутри метода onComplete, он будет выполняться в основном потоке?   -  person Rainmaker    schedule 07.04.2017


Ответы (2)


  1. Вы не можете передать Object в onComplete(), так как onComplete() не имеет значений, это сигнал о том, что потоки заканчиваются, и элементы больше не будут выдаваться.
    вы можете передавать его в onNext() при каждой эмиссии (т.е. обернуть 2 объекта с кортежем, как предложил @akarnokd) и удалите его там.

  2. вы можете просто писать весь код непрерывно с помощью анонимных методов, и если вы будете использовать лямбда-выражения, это сократит больше стандартного кода.

  3. если вы удалите файл в onCompleted, он действительно будет выполнен в основном потоке, как вы укажете в observerOn().

В любом случае, вам не нужно делать это в событии onCompleted(), просто удалите его в коде подписки (метод create) после того, как вы извлекли растровое изображение в память, подписчик не должен знать или заботиться о том, как извлекается Bitmap. кроме того, вы можете использовать fromCallable(), то есть обернуть его методом, который выполняет все операции. подвести итог:

 Observable.fromCallable(() -> {
        File outputFile = new File(newTAG);
        // do some stuff with a file
        Bitmap bitmap = decodeSampledBitmapFromUrl(newTAG, width, height);
        // be sure to handle properly exceptions for ensure file will be closed
        outputFile.delete();
        return bitmap;
    })
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(bitmap -> {
                        if (mImageView.getTag().toString().equals(TAG)) {
                            mImageView.setImageBitmap(bitmap);
                        }
                    },
                    throwable -> {
                        //handle error
                    });
person yosriz    schedule 07.04.2017

Вы можете использовать интерфейс вместо выполнения операции в onComplete() или onNext().

Создать интерфейс

public interface OnActionComplete {
    void onComplete();
}

Реализуйте его в своей деятельности или фрагменте

public class YourActivity extends BaseActivity implements OnActionComplete {
    @Override
    public void onComplete() {
        //perform your action
    }
}

Теперь просто вызовите этот метод по завершении вашей задачи, например onNext.

@Override
public void onNext(Bitmap bitmap) {
    if(mImageView.getTag().toString().equals(TAG)) {
        mImageView.setImageBitmap(bitmap);

        activityInstance.onComplete(); // this will trigger onComplete() method of interface.
    }
}
person Uttam Panchasara    schedule 07.04.2017