RXJava 将一个值传递给 onComplete

RXJava pass a value into 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. 有没有一种方法可以在一个事件中或在更少的代码中创建可观察对象并订阅它?
  1. 您不能将对象传递给 onComplete(),因为 onComplete() 没有值,这是流结束的信号,不会有更多项目发射。
    您可以在每次发射时在 onNext() 处传递它(即用 @akarnokd 建议的元组包装 2 个对象)并在那里删除它。

  2. 您可以简单地使用匿名方法连续编写所有代码,如果您将使用 lambdas,它将减少更多样板代码。

  3. 如果您要在 onCompleted 处删除文件,它确实会在主线程中执行,正如您通过 observerOn() 指定的那样。

无论如何,您不必在 onCompleted() 事件上执行此操作,只需在将位图提取到内存后在订阅代码(创建方法)上删除它,订阅者不应该这样做知道或关心 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
                    });

您可以使用接口而不是在 onComplete() 或 onNext() 中执行操作。

创建接口

public interface OnActionComplete {
    void onComplete();
}

在您的 Activity 或 Fragment

中实现它
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.
    }
}