Skip to content

Android

IvanYH Wu edited this page Apr 23, 2025 · 9 revisions

Download

First, you can add this repository to the root of your project build.gradle file under the allprojects.

allprojects {
  repositories {
   ...
   maven { url 'https://jitpack.io' }
  }
}

or add Jitpack in settings.gradle

ependencyResolutionManagement {
    ...
    repositories {
        ...
        maven { url 'https://jitpack.io' } // Add this line
    }
}

Then, add this dependency to the build.gradle file in app directory.

dependencies {
    implementation "com.github.ivanisidrowu.KtRssReader:android:v2.2.3"
}

If you want to customize data format, you have to add these dependencies.

apply plugin: 'com.google.devtools.ksp'

dependencies {
    implementation "com.github.ivanisidrowu.KtRssReader:android:v2.2.3"
    implementation "com.github.ivanisidrowu.KtRssReader:annotation:v2.2.3"
    ksp "com.github.ivanisidrowu.KtRssReader:processor:v2.2.3"
}

Data Models

Before we get into the basic API usage, let's talk about the data models in KtRssReader. KtRssReader provides 4 model classes and custom annotations for you to get different kinds of tags you need. You can check on Data Models.

Custom Data

In KtRssReader, we provide annotations to let you define custom models.

  • Don't forget to rebuild the project after defining custom data classes with annotations!
  • Remember, every custom data class is required to implement Serializable.

@RssTag

Params:

  • name: The tag name in String.
  • order: Custom parsing order array. The type in the array is OrderType enum. 3 types are available, RSS_STANDARD, ITUNES, GOOGLE. The default order array is [OrderType.RSS_STANDARD, OrderType.ITUNES, OrderType.GOOGLE]. When parsing the RSS feed, the parser will follow the order to find the available value for the property. Take the default order array as an example, the parser will check the RSS standard tag value first, if it has a value, it will not check the iTunes tag and put the RSS standard tag value to the custom model. Otherwise, it will continue to find an available value.

Class example:

@RssTag(name = "channel")
data class MyChannel(
    val title: String?,
    @RssTag(name = "author", order = [OrderType.ITUNES, OrderType.RSS_STANDARD])
    val name: String?,
): Serializable

Data example:

<channel>
    <title>the title</title>
    <author>the author</author>
    <itunes:author>itunes author</itunes:author>
</channel>

@RssAttribute

Params:

  • name: The name of the attribute.

Class example:

@RssTag(name = "category")
data class Category(
    @RssAttribute(name = "title")
    val categoryTitle: String?,
): Serializable

Data example:

<category title = "the title">this is a category</category>

The value of the categoryTitle will be "the title".

@RssValue

Get the value inside a tag.

Class example:

@RssTag(name = "category")
data class Category(
    @RssValue
    val value: String?,
    @RssAttribute
    val title: String?,
): Serializable

Data example:

<category title = "the title">this is a category</category>

In this case, the property value of the data class will be "this is a category".

@RssRawData

An annotation to let you parse tags with specific raw data in RSS feed.

Params:

  • rawTags: It's an array that contains tag names you would like to parse, and the parser will follow the order of the array to find tag candidates.

Class example:

@RssTag(name = "channel")
data class RawRssData(
    @RssRawData(rawTags = ["googleplay:author", "itunes:author"])
    val author: String?,
    val title: String?,
): Serializable

Data example:

<channel>
    <itunes:author>itunes author</itunes:author>
    <titile>title</title>
</channel>

The parsing result of the author, in this case, will be "itunes author" because the tag <googleplay:author> does not exist in the data. So the parser uses the backup tag <itunes:author> defined in @RssRawData.

Reader Code Generation

After you define your custom data, KtRssReader will generate reader code for you. For instance, if I defined a data class named PodcastChannel which has the data of the <channel> tag, the KtRssReader will automatically generate PodcastChannelReader after rebuilding the project.

How to Use KtRssReader?

Basic Usage

val result: RssStandardChannelData = Reader.read<RssStandardChannelData>(rssSource)

This is the simplest way to use it. As you can see, Reader.read() takes a generic type called RssStandardChannelData. You can also use alternatives such as ITunesChannelData or AutoMixChannelData depends on you what you need. Alternative classes can found in Channels.kt. The reader method should not be executed in the main thread or it will throw an exception to warn lib users.

With Flow

Reader.flowRead<AutoMixChannelData>(rssSource)
    .flowOn(Dispatchers.IO)
    .collect { data ->
        Log.d("KtRssReader", data)
    }

With Coroutines

coroutineScope.launch(Dispatchers.IO) {
    val result = Reader.coRead<GoogleChannelData>(rssSource)
    Log.d("KtRssReader", result)
}

With Custom Data

  1. Define your custom data classes.
@RssTag(name = "channel")
data class PodcastChannel(
    val title: String?,
    @RssTag(name = "author", order = [OrderType.ITUNES, OrderType.RSS_STANDARD])
    val podcastAuthor: String?,
): Serializable
  1. Rebuild the project.

  2. PodcastChannelReader will be generated automatically.

  3. Use PodcastChannelReader as we mentioned in Basic Usage.

val result: PodcastChannel = PodcastChannelReader.read(rssSource)

// Flow
PodcastChannelReader.flowRead(rssSource)
    .flowOn(Dispatchers.IO)
    .collect { data ->
        Log.d("KtRssReader", data)
    }

// Coroutines
val coResult: PodcastChannel = PodcastChannelReader.coRead(rss)

With Custom fetcher

  1. Implement your custom fetcher with the Fetcher interface.
class XmlFetcher : Fetcher {

    override fun fetch(url: String, charset: Charset?): String {
        val request = Request.Builder()
            .url(url)
            .header("User-Agent", "custom user agent")
            .build()
        val response = OkHttpClient().newCall(request).execute()
        return response.body?.toString() ?: throw IOException("Failed to get the response body!")
    }

}
  1. Use it in the read, coRead, and flowRead.
val customFetcher = XmlFetcher()
val result = Reader.read<RssStandardChannelData>(url = rssSource, fetcher = cutsomFetcher)

Clear Cache

Clear all cache in the database.

Reader.clearCache()

Config

Global Config

class MyApplication : Application() {
    override fun onCreate() {
        readerGlobalConfig {
            enableLog = true
        }
    }
}
  • enableLog: If this is enabled, the debug log will be shown on the console.

Reader Config

val result: ITunesChannelData = Reader.read<ITunesChannelData>(rssSource) {
    charset = Charsets.UTF_8
    useCache = false
    expiredTimeMillis = 600000L
}
  • charset: Specify an encoding charset, if it's not set, it will use the charset from the RSS source.
  • useCache: Pull data from cache or remote server. The default setting is set to true.
  • flushCache: Clear the specific cache by URL.
  • expiredTimeMillis: The cache expired time in milliseconds.

Samples

The sample App is in /app folder. Check it out!