如何在rxJava中手动调用observer.onNext

时间:2016-12-21 13:18:50

标签: android android-asynctask rx-java rx-android

我对RxJava / RxAndroid比较新。我之前一直在使用AsyncTask完成我的长期运行任务。 我已经将我的大部分AsyncTask转换为RxJava但是这个。 我遇到的特殊问题是调用类似AsyncTask的publishProgress(params); 后台线程。我需要这样做才能更新ProgressBar

的进度

首先这是AsyncTask中的代码

private static class AddBooksToDatabase extends AsyncTask<String, String, String> {
    //dependencies removed

    AddBooksToDatabase(AddBooksDbParams params) {
        //Removed assignment codes
    }

    @Override
    protected String doInBackground(String... strings) {
        //Initializing custom SQLiteOpenHelper and SQLite database
        File mFile = new File(mFolderPath);

        int booksSize = getFilesInFolder(mFile).size();
        String[] sizeList = {String.valueOf(booksSize)};
        //The first publishProgress is used to set the max of the progressbar
        publishProgress(sizeList);

        for (int i = 0; i < booksSize; i++) {
            //publishProgress with current item, current file
            publishProgress(String.valueOf(i), getFilesInFolder(mFile).get(i).getName());
            //Inserting current items in database. Code removed
        }
        return null;
    }

    @Override
    protected void onPreExecute() {
        //Show ProgressBar
    }

    @Override
    protected void onPostExecute(String s) {
        //Hide ProgressBar
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        if (values.length == 1) {
            //The first call to publishProgress
            mProgressBar.setMax(Integer.parseInt(values[0]));
        } else {
            //Subsequent calls to publish progress
            Log.i(TAG, "Current item is " + values[0] + " and current file is " + values[1]);
            infoText.setText(values[1]);
            mProgressBar.setProgress(Integer.parseInt(values[0]), true);

        }
    }

    @Override
    protected void onCancelled() {
        cancel(true);
    }
}

使用RxJava的代码

final Observable<String[]> addBooksObserver = Observable.create(new Observable.OnSubscribe<String[]>() {
        @Override
        public void call(Subscriber<? super String[]> subscriber) {
            subscriber.onNext(setAddSubscription());
            subscriber.onCompleted();
        }
    })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());

private String[] setAddSubscription() {
    S//Initializing custom SQLiteOpenHelper and SQLite database
    File mFile = new File(mFolderPath);

    int booksSize = getFilesInFolder(mFile).size();
    String[] sizeList = {String.valueOf(booksSize)};
    //The first publishProgress is used to set the max of the progressbar
    addBooksObserver.doOnNext(addReturnParams(String.valueOf(sizeList.length), null, null));

    for (int i = 0; i < booksSize; i++) {
        EpubReader reader = new EpubReader();
        //publishProgress with current item, current file*
        addBooksObserver.doOnNext(addReturnParams(String.valueOf(sizeList.length),
                String.valueOf(i), getFilesInFolder(mFile).get(i).getName()));
        //Inserting current item in database. Code removed
    }
    return null;
}

private String[] addReturnParams(String totalItems, String currentItem, String currentFile) {
    return new String[]{totalItems, currentItem, currentFile};
}

问题是第addBooksObserver.doOnNext(addReturnParams(行显示此错误      doOnNext(rx.functions.Action1)无法应用于(java.lang.String [])

我不知道如何解决这个问题因为我认为,因为setAddSubscription()addReturnParams(String totalItems, String currentItem, String currentFile)正在返回String数组,所以这应该不是问题。请你帮帮我吗?

4 个答案:

答案 0 :(得分:1)

您只需将值传递给onNext的{​​{1}}方法,您观察到的subscriber方法!

您还必须订阅该服务。尝试这样的事情是为了你的想法:

doOnNext

您还需要稍微修改一下私有方法:

Observable.create(new Observable.OnSubscribe<String[]>() {
  @Override
  public void call(Subscriber<? super String[]> subscriber) {
    setAddSubscription(subscriber);
    subscriber.onCompleted();
  }
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String[]>() {
  @Override
  public void onCompleted() {
   // handle 'oparation is done'
  }

  @Override
  public void onError(Throwable e) {

  }

  @Override
  public void onNext(String[] values) {
    if (values.length == 1) {
        //The first call to publishProgress
        mProgressBar.setMax(Integer.parseInt(values[0]));
    } else {
        //Subsequent calls to publish progress
        Log.i(TAG, "Current item is " + values[0] + " and current file is " + values[1]);
        infoText.setText(values[1]);
        mProgressBar.setProgress(Integer.parseInt(values[0]), true);

    }
  }
});

答案 1 :(得分:0)

您的Observer应该像Observable.create(new Observable.OnSubscribe<String>()&amp;在call方法中,您应该遍历StringArray&amp;将其传递给onNext,例如:

@Override
public void call(Subscriber<? super String> subscriber) {
   for(String val : setAddSubscription()) {
       subscriber.onNext(val);
   }
   subscriber.onCompleted();
}

现在onNext将返回您的个别物品&amp;循环结束后将调用onCompleted

修改

myObserver.subscribe(new Subscriber<String>() {
  @Override
  public void onCompleted() {
   // handle completion. 
  }

  @Override
  public void onError(Throwable e) {

  }

  @Override
  public void onNext(String value) {
    // do whatever with each value passed to onNext
  }
});

答案 2 :(得分:0)

Observable.create(emitter -> {
            for (int i = 0; i < 10; i++) {
                int[] ii = {i, i * 2};
                emitter.onNext(ii);
            }
            emitter.onComplete();
        }).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(o -> {
            // update progress
            int[] i = (int[]) o;
            Toast.makeText(SearchActivity.this, "oftad " + i[0] + " - " + i[1], Toast.LENGTH_SHORT).show();

        }, t -> {
            // on error
            Toast.makeText(SearchActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
        }, () -> {
            // progress tamom shod
            Toast.makeText(SearchActivity.this, "completed", Toast.LENGTH_SHORT).show();
        });

答案 3 :(得分:0)

您可以像这样使用Subject手动调用onNext():

 Subject<Event> event = Subject.create();

现在调用onNext()发送事件,例如:

 event.onNext("event");

最后,您可以使用以下代码返回Observable

event.toFlowable(BackpressureStrategy.LATEST)
                .toObservable();