我想创建一个按需发出项目的Observable,这意味着我想要一个订阅Observable,并根据我的请求通知Observable我需要新项目。
这是我使用PublishSubject所做的:
public class RecognizeSubject {
PublishSubject<Bitmap> mSubject;
private Context mContext;
private FaceDetector mFaceDetecor;
public RecognizeSubject(Context mContext) {
this.mContext = mContext;
this.mSubject = PublishSubject.create();
}
public void detect(Bitmap btm){
mSubject.onNext(btm);
}
public Flowable<SinglePhotoId> execute() {
return mSubject.toFlowable(BackpressureStrategy.DROP)
.observeOn(Schedulers.newThread())
.map(bitmap1 -> recognize(bitmap1))
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(disposable -> initialize())
.doFinally(() -> release());
}
private void initialize() {
mFaceDetecor = new FaceDetector.Builder(mContext)
.setTrackingEnabled(false)
.setLandmarkType(FaceDetector.ALL_LANDMARKS)
.build();
}
private void release() {
if (mFaceDetecor != null)
mFaceDetecor.release();
}
private SinglePhotoId recognize(Bitmap bitmap) {
//SystemClock.sleep(3000);
//make hard background work and return SinglePhotoId object
}
}
这是Activity类中的用法:
private void takeSubjectSnap() {
if (mSubject == null)
mSubject = new RecognizeSubject(getBaseContext());
if (mDisposable == null || mDisposable.isDisposed()) {
mDisposable = mSubject.execute()
.subscribe(this::handleDetectionSuccess,
this::handleDetectionError,
this::handleDetectionCompleted);
}
mSnapshotButton.setProgress(true);
mSubject.detect(myVideoView.getBitmap());
}
所以基本上我订阅Flowable对象并将Bitmap对象传递给我的Subject类继续并通过Flowable返回结果,该解决方案是正确的还是会产生一些内存泄漏?
有没有更好的解决方案将对象发送到Observable继续并通过标准的onNext()方法返回结果?
答案 0 :(得分:0)
在这种情况下,RxRelays非常方便
答案 1 :(得分:0)
(我将此作为评论,因为这不是一个答案,但它太长了)
我不确定这里的用例是什么,以及您正在尝试实现的内容,因为您描述和实施的内容略有不同。
您所描述的是一种能够处理某些内容并在其自由/能够处理/等时请求新内容的机制
您实现的是一种基于推送的处理器处理项目的机制,具体取决于它从客户端接收的数据。
因此,如果您实施的内容按照您的要求正常运行,那么我会提出一些改变:
execute
方法重命名为其他方法(因为它不会执行任何操作)disposable
初始化Disposables.disposed()
以避免空检查RecognizeSubject
重命名为其他内容,因为它正在泄漏有关其内部实施的信息。mSubject
private
和final
我并不确定在使用位图时是否可以使用可流动的东西,您确定需要同时处理多个位图并处理所有位图(并删除那些未处理的位图吗?)。
答案 2 :(得分:0)
好的,我已经阅读了您的答案并稍微更改了我的代码,这是一个图表,说明了我想要实现的目标:
所以我的Subject类将处理后台线程上的接收数据,并通过onNext()方法将处理过的项目发送到它们的Observer。我创建了一个简单的Subject,它接收Integer对象并将其转换为String对象,这里是代码:
fadeOut fadeOut fadeIn
}
这是Activity类中的用法:
public class MySubject {
private String TAG = "MySubject";
private PublishSubject<Integer> subject;
private final Observable<String> observable;
public MySubject() {
Log.d(TAG, "---> MySubject() called");
this.subject = PublishSubject.create();
this.observable = subject
.doOnSubscribe(disposable -> init())
.doFinally(() -> relese()) //try do after terminate
.observeOn(Schedulers.newThread())
.map(this::myMap)
.observeOn(AndroidSchedulers.mainThread());
}
private void init(){
Log.d(TAG, "---> init() called");
}
private void relese(){
Log.d(TAG, "---> relese() called");
}
private String myMap(Integer integer){
Log.d(TAG, "---> myMap() called int: " + integer);
SystemClock.sleep(3000);
return " :) " + String.valueOf(integer);
}
public void decode(Integer integer){
subject.onNext(integer);
}
public Observable<String> getObservable(){
return observable;
}
每次调用onButton1()方法时,我都会将新的随机int发布到主题对象,然后在完成后通过onNext()方法接收处理过的数据。
该解决方案是否正确并且不会导致任何副作用或内存泄漏? 当然我在Activity的onStop()方法中取消订阅主题。 也许有更好的解决方案来处理Rxjava中的这类问题?
任何进一步的答案将不胜感激:)