从可观察的Single <list>获取列表

时间:2018-08-16 06:28:33

标签: android kotlin rx-java reactive-programming rx-android

我有一个返回Single<List<HistoryItem>>的方法。现在我要从中获取列表。

private fun getListOfDownload(): ArrayList<HistoryItem> {
    val downloads = manager.lastHundredVisitedHistoryItems()
    downloads.subscribe { t ->
        return t; // not allowed
    }
}

我可以使用subscribe,但这不允许我从中返回列表。

我也尝试过map

downloads.map { t: List<HistoryItem> -> return t } // again `return t` is not allowed.

修改

我可以通过关注

private fun getListOfDownload(): ArrayList<HistoryItem> {
        var list = ArrayList<HistoryItem>()
        val downloads = manager.lastHundredVisitedHistoryItems()
        downloads.subscribe { t ->
            list = t as ArrayList<HistoryItem>
        }
        return list
    }

请告诉

  • 如果这种方法正确并且不会阻塞主线程?
  • 是否有办法在不声明另一个声明的情况下返回列表 清单?

我是Reactive编程的新手,请给我解释一下。

3 个答案:

答案 0 :(得分:1)

我认为订阅lambda为crossinline,这意味着它不允许本地返回

您通常会在subscribe{}中使用列表进行更新(更新recyclerView)

例如

val compositeDisposable = CompositeDisposable()

private fun downloadList() {
    manager.lastHundredVisitedHistoryItems()
        downloads.subscribe { downloadedList ->
            this.list = downloadedList
            // or
            adapter.updateDataSet(downloadedList)
        }.addTo(compositeDisposeable)
    }
}

您还需要将您的一次性用品添加到CompositeDisposable中,以防止出现记忆韭葱的可能性

答案 1 :(得分:1)

在您的代码中getListOfDownload返回ArrayList<HistoryItem>,而lastHundredVisitedHistoryItems中的manager返回Single<ArrayList<HistoryItem>>,这意味着您要观察ArrayList<HistoryItem> ,因为lastHundredVisitedHistoryItems需要花费一些时间。

这就是为什么您不能在subscription块中返回该项目的原因,因为该块是lamda,它将观察ArrayList<HistoryItem>项。

但是,如果您不关心观察结果,则可以执行以下操作,

private fun getListOfDownload(): ArrayList<HistoryItem> {
    val downloads = manager.lastHundredVisitedHistoryItems()
    return downloads.blockingGet()
}

但是当我们应用lastHundredVisitedHistoryItems 时,您失去了blockingGet()的异步调用,但是由于您没有在单独的线程上观察到它,我假设您想在主线程上调用它。

但是,如果您想观察lastHundredVisitedHistoryItems(),则可以将方法作为参数传递,该参数将充当ArrayList<HistoryItem>的消费者。

private fun getListOfDownload( listener : (ArrayList<LoginViewModel.HistoryItem>) -> Unit) {
        val downloads = manager.lastHundredVisitedHistoryItems()
        downloads.subscribe { t -> listener.invoke(t) }
}

// when you call above method look like below
// here variable `it` is nothing but a object of ArrayList<LoginViewModel.HistoryItem>
getListOfDownload { adapter.updateDataSet(it) }

答案 2 :(得分:0)

您可以按照以下方式使用订阅获取列表:

 @NonNull
public Single<String> getHistoryPage() {
    return Single.create(new SingleAction<String>() {
        @Override
        public void onSubscribe(@NonNull final SingleSubscriber<String> subscriber) {


            mHistoryModel.lastHundredVisitedHistoryItems()
                    .subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
                        @Override
                        public void onItem(@Nullable List<HistoryItem> item) {
                      final StringBuilder historyBuilder = new StringBuilder(HEADING_1 + mTitle + HEADING_2);      

                            Iterator<HistoryItem> it = item.iterator();
                            HistoryItem helper;
                            while (it.hasNext()) {
                                helper = it.next();
                                historyBuilder.append(PART1);
                                historyBuilder.append(helper.getUrl());
                                historyBuilder.append(PART2);
                                historyBuilder.append(helper.getTitle());
                                historyBuilder.append(PART3);
                                String url = helper.getUrl();
                                try {
                                    URL url1 = new URL(url);
                                    authority = url1.getAuthority();
                                } catch (MalformedURLException e) {
                                    e.printStackTrace();
                                }
                                historyBuilder.append(authority);   //No need of path showing of History file.
                                historyBuilder.append(PART4);
                            }

                            historyBuilder.append(END);
                            File historyWebPage = getHistoryPageFile(mApp);
                            FileWriter historyWriter = null;
                            try {
                                //noinspection IOResourceOpenedButNotSafelyClosed
                                historyWriter = new FileWriter(historyWebPage, false);
                                historyWriter.write(historyBuilder.toString());
                            } catch (IOException e) {
                                Log.e(TAG, "Unable to write history page to disk", e);
                            } finally {
                                Utils.close(historyWriter);
                            }

                            subscriber.onItem(Constants.FILE + historyWebPage);
                            subscriber.onComplete();
                        }
                    });
        }
    });
}

通过使用以上代码,您可以在html页面中获取历史记录列表。您必须为此使用StringBuilder,然后获得完整的历史记录页面