Creating a producer that fetches feeds on demand

Now we will create the producer. To do so, let's first create a package co.starcarr.rssreader.producer and put the file ArticleProducer.kt inside it:

In that file, we will create an object ArticleProducer and we will move some of the code from the activity there, starting with the list of feeds:

object ArticleProducer {
private val feeds = listOf(
Feed("npr", "https://www.npr.org/rss/rss.php?id=1001"),
Feed("cnn", "http://rss.cnn.com/rss/cnn_topstories.rss"),
Feed("fox", "http://feeds.foxnews.com/foxnews/latest?format=xml")
)
}
Notice that we are removing the invalid feed for now.

We will also move the dispatcher and the factory here:

object ArticleProducer {

...
private val dispatcher = newFixedThreadPoolContext(2, "IO")
private val factory = DocumentBuilderFactory.newInstance()
}

Finally, we will move the function asyncFetchArticles(). Now, it will be called fetchArticles() and will return a List<Article> directly:

object ArticleProducer {

...

private fun fetchArticles(feed: Feed) : List<Article> {
...
}
}

In order for this function to compile, we will have to add a return statement at the end of it. Something simple like the following will work:

private fun fetchArticles(feed: Feed) : List<Article> {
val builder = factory.newDocumentBuilder()
val xml = builder.parse(feed.url)
val news = xml.getElementsByTagName("channel").item(0)

return (0 until news.childNodes.length)
.map { news.childNodes.item(it) }
.filter { Node.ELEMENT_NODE == it.nodeType }
.map { it as Element }
...
}
If you still had the call delay() that we added in a previous chapter inside this function, please remove it as well – this function is no longer suspending, so it can't call other suspending functions unless we use a coroutine builder.

So we are only missing the actual producer. Since we want to fetch each feed on demand, we only need to iterate through the list of feeds, sending the articles of each feed. A simple implementation would be the following:

val producer = produce(dispatcher) {
feeds.forEach {
send(fetchArticles(it))
}
}

Notice that now we are sending all the articles of each feed through the producer. So this is a Producer<List<Article>>.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.146.176.88