繁体   English   中英

如何在RXJava Android中对后台线程执行长时间的计算

[英]How perform long calculations on background thread in RXJava Android

我想在android中使用RXJava在后台线程上执行长时间的计算。 经过计算,我试图在Recylerview中显示结果。 我正在使用以下代码:

 Observable.just("true") .subscribeOn(Schedulers.io()) .map(new Func1<String, String>() { @Override public String call(String s) { feedlist.clear(); if (eventFeedItems != null && !eventFeedItems.isEmpty()) { for (int i = 0; i < eventFeedItems.size(); i++) { if (eventFeedItems != null && eventFeedItems.get(i) != null && ((eventFeedItems.get(i).getType() != null && eventFeedItems.get(i).getType().equalsIgnoreCase("EVENT")) || (eventFeedItems.get(i).getActivityRequestType() != null && eventFeedItems.get(i).getActivityRequestType().equalsIgnoreCase(EventConstants.TRENDING_ACTIVITY)))) { if (eventFeedItems.get(i).getActivityRequestType() != null && !eventFeedItems.get(i).getActivityRequestType().equalsIgnoreCase("")) { feedlist.add(new FeedsListModel(eventFeedItems.get(i), eventFeedItems.get(i).getActivityRequestType(), null)); } else if (eventFeedItems.get(i).getRequestType() != null && !eventFeedItems.get(i).getRequestType().equalsIgnoreCase("")) { feedlist.add(new FeedsListModel(eventFeedItems.get(i), eventFeedItems.get(i).getRequestType(), null)); } else feedlist.add(new FeedsListModel(eventFeedItems.get(i), EventConstants.ATTENDEE_POST, null)); } } } Log.d("calculations","Completed"); return ""; } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String s) { // feed_list.setLayoutManager(mLayoutManager); // feedListAdapter.notifyDataSetChanged(); Log.d("Adapter", "Set"); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { Log.d("Exception", "oh! fish..."); throwable.printStackTrace(); } }); 

使用上面的代码,我面对的是UI Hindring,因为ArrayList的eventFeedItems大小大约有300个以上的项目。我是RXJava的新手。 请帮帮我。

你不会使用map-Operator实现并发。

第一个subscribeOn将所有emitions移动到IO调度程序。 这里没有发生并发。

.subscribeOn(Schedulers.io())

map-operator将从前一个线程同步调用。 在你的情况下,它将是来自IO-threadpool的一些线程。

.map(new Func1<String, String>() {

执行map-Operator后,您将把值从IO线程移动到Android-UI-event-loop

.observeOn(AndroidSchedulers.mainThread())

将值从IO线程转换为UI线程后,将处理初始observable的下一个值。

Observable.just("true")

在您的示例中,将不再有值,因为您只生成一个值。

为了实现并发,您应该使用flatMap而不是map。 并在flatMap中使用subscribeOn()在另一个线程上创建每个流。

请考虑此示例,以了解并发性如何发生。 每个可观察者都会立即订阅,所以最大值。 teset的时间约为5秒。 如果现在发生并发,则需要1 + 2 + 3 + 4 + 5秒加上执行时间。

@Test
public void name1() throws Exception {

        Observable<Integer> value = Observable.just(1_000, 2_000, 3_000, 4_000, 5_000)
                .flatMap(i -> Observable.fromCallable(() -> doWork(i)).subscribeOn(Schedulers.io())
                ).doOnNext(integer -> System.out.println("value"));

        value.test().awaitTerminalEvent();
}

private int doWork(int sleepMilli) {
        try {
            Thread.sleep(sleepMilli);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return -1;
}

如果您想了解更多关于flatMap如何发生并发的信息,请考虑阅读http://tomstechnicalblog.blogspot.de/2015/11/rxjava-achieving-parallelization.html

关于你的代码,我建议:

  • 将anonymouse接口的实现移动到私有内部类实现并使用它的实例。 您将获得更易读的可观察性
  • 不要将副作用用于来自其中的运算符的全局变量。 如果涉及并发性,您将获得竞争条件。

     List<FeedsListModel> eventFeedItems = Arrays.asList(new FeedsListModel(), new FeedsListModel()); Observable<FeedsListModel> feedsListModelObservable = Observable.fromIterable(eventFeedItems) .flatMap(feedsListModel -> Observable.fromCallable(() -> calculation(feedsListModel)) .subscribeOn(Schedulers.computation()) ); feedsListModelObservable .toList() .observeOn(Schedulers.io()) .subscribe(feedsListModels -> { // do UI stuff }); 

帮助法:

private FeedsListModel calculation(FeedsListModel model) {
    // do calculation here

    return new FeedsListModel();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM