Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
KtRssReader 的奇幻旅程
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Ivan
March 23, 2021
120
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
KtRssReader 的奇幻旅程
Ivan
March 23, 2021
More Decks by Ivan
See All by Ivan
Kotlin Flow Application and Testing on Android
ivanw
0
330
Kotlin Flow Application and Testing on Android
ivanw
1
470
A Step-by-Step Guide to Kotlin Flow 手把手帶你認識 Kotlin Flow
ivanw
0
240
Coroutines Made Easy
ivanw
1
200
All About KotlinConf 2019
ivanw
0
130
Writing Tests in Kotlin
ivanw
0
360
Using Kotlin in Android
ivanw
0
120
Featured
See All Featured
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
66
55k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
440
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
370
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
Six Lessons from altMBA
skipperchong
29
4.3k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.5k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
Navigating Team Friction
lara
192
16k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.4k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
Transcript
KtRssReader 的奇幻旅程 Ivan & 小汪 1
• 為什麼要做 KtRssReader ? • KtRssReader 簡介與用法 • 實作方式 •
程式碼發佈方式 • 未來方向 Outline 2
Rss Feed 為什麼要做KtRssReader ? 3
<?xml version="1.0"?> <rss version="2.0"> <channel> <image> <link>http://channel.image.link</link> <title>channel image title</title>
<url>http://channel.image.url</url> <description>channel image description</description> <height>32</height> <width>96</width> </image> </channel> </rss> RSS 2.0 4
<?xml version="1.0" encoding="UTF-8"?> <rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"> <channel> <itunes:image href="https://channel.image.itunes" />
<image> <link>http://channel.image.link</link> <title>channel image title</title> <url>http://channel.image.url</url> <description>channel image description</description> <height>32</height> <width>96</width> </image> </channel> </rss> iTunes 5
<?xml version="1.0"?> <rss xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"> <channel> <googleplay:image href="http://channel.image" />
<itunes:image href="https://channel.image" /> <image> <link>http://channel.image</link> <title>channel image title</title> <url>http://channel.image.url</url> <description>channel image description</description> <height>32</height> <width>96</width> </image> </channel> </rss> Mixing 6
<?xml version="1.0"?> <rss xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"> <channel> <itunes:image href="https://channel.image.itunes" />
<image> <link>http://channel.image.link</link> <title>channel image title</title> <url>http://channel.image.url</url> <description>channel image description</description> <height>32</height> <width>96</width> </image> </channel> </rss> 遇到的情況 7
8
9
• 每則 Rss Feed 提供的 Tag 資訊不一 • 自己制定自己想要讀取順序,減少開發成本 問題總結
10
◦ Easy-to-use API ◦ Fetches feed for you ◦ Database
cache and custom cache valid time ◦ Supports RSS 2.0 standard, iTunes, and Google Play tags ◦ Customizes output data with annotations KtRssReader 簡介 11
MainScope().launch { val rssData = withContext(Dispatchers.IO) { Reader.coRead<ITunesChannelData>(url) { useCache
= true expiredTimeMillis = 3.days.toLongMilliseconds() charset = Charsets.UTF_8 } } print(rssData) } • Reader.read() • Reader.flowRead() 基礎使用 12
• RssStandardChannelData • ITunesChannelData • GoogleChannelData • AutoMixChannelData ( RssStandard
> iTunes > GooglePlay ) Channel Data 13
annotation class RssTag( val name: String = "", val order:
Array<OrderType> = [OrderType.RSS_STANDARD, OrderType.ITUNES, OrderType.GOOGLE] annotation class RssRawData(val rawTags: Array<String>) RssTag 14
@RssTag(name = "channel") data class CustomChannelData( @RssTag(name="title",order = [OrderType.GOOGLE, OrderType.ITUNES,
OrderType.RSS_STANDARD]) val rssTitle: String?, @RssRawData(["itunes:summary", "googleplay:description", "googleplay:summary"]) val description: String?, ) : Serializable Custom RSS Data 15
• Parser 實作面向 ◦ 標準 TAG Parser ▪ RSS 2.0
▪ Google ▪ iTunes ▪ Auto Mixed (All together) ◦ 自定義 Parser ▪ Annotation ▪ KAPT 實作方式 16
• Kotlin Parser ◦ 使用 DOM Parser ▪ 方便跨層尋找 TAG
• 可以處理 TAG 內夾帶 HTML 碼的情況 ▪ RSS 檔案大的時候,比較耗記憶體 ▪ 若有相同 TAG 且多筆資料,需判斷他的父節點 ◦ 實作 ▪ RssStandardParser.kt, GoolgeParser.kt, ITunesParser.kt , AutoMixParser.kt 標準 TAG Parser 17
• Android Parser ◦ 使用 Android 原生 XmlPullParser ▪ 比
DOM parser 省記憶體 ▪ 速度比 SAX 快 ▪ Event Stream 方式載入 TAG ◦ 實作 ▪ AndroidRssStandardParser.kt, AndroidGoogleParser.kt, AndroidITunesParser.kt, AndroidAutoMixParser.kt 標準 TAG Parser 18
哇,是自定義 Parser ? 19
• Annotation ◦ @RssTag ◦ @RssAttribute ◦ @RssValue ◦ @RssRawData
自定義 Parser 20
• 這樣訂的好處 ◦ 可以知道使用者想爬到的資料結構長怎樣 ◦ 用不同的 Annotation 知道資料的類型,像是 Tag、Attribute、Value等 ◦
如果資料的 TAG 長得很特別也可以用 @RssRawData 爬 ▪ <yoyoyo:checkitout> 自定義 Parser 21
• Annotation Processor ◦ KAPT, Kotlin annotation processing tool ◦
讓我們可以讀到 annotation 標記的 class、method、variable 等 • Kotlin Poet ◦ 用來產生 Kotlin 程式碼的程式庫 ◦ 用簡單易懂的語法在 building 的時候就可以產生程式碼 ▪ 支援 Control flow ▪ 有各種 Type 和 Class 的表達式 自定義 Parser 22
• 新增一個 module 放 annotation • 新增一個 module 放 processor
apply plugin: 'kotlin-kapt' dependencies { implementation 'com.squareup:kotlinpoet:1.6.0' implementation "com.google.auto.service:auto-service:1.0-rc6" } Annotation Processor 23
• 在 processor/src/main/resources/META-INF/services/ 下 ◦ 新增 javax.annotation.processing.Processor 檔案 ◦ 裡面寫你的
processor 的 package name 完整路徑 Annotation Processor 24
• 開始寫屬於你的 processor @AutoService(Processor::class) class RssAnnotationProcessor : AbstractProcessor() { override
fun getSupportedAnnotationTypes(): MutableSet<String> { return mutableSetOf( RssTag::class.java.canonicalName, RssRawData::class.java.canonicalName, RssAttribute::class.java.canonicalName, RssValue::class.java.canonicalName ) } override fun process(typeElementSet: MutableSet<out TypeElement>?, roundEnvironment: RoundEnvironment?): Boolean { ... } } https://github.com/ivanisidrowu/KtRssReader/blob/master/processor/src/main/java/tw/ktrssreader/processor/RssAnnotationProcessor.kt Annotation Processor 25
• 如果我要做多個不同用途的 annotation processor ,該怎麼辦? ◦ 創不同的 module ▪ 分包讓使用者
load 進去 ◦ 有共用邏輯的話,可以用 kapt arguments kapt { arguments { arg("pureKotlinParser", true) } } val isPureKotlinParser = processingEnv.options["pureKotlinParser"]?.toBoolean() ?: false Annotation Processor 26
• 實作各種不同的 generator ◦ Kotlin ▪ KotlinParserGenerator.kt ▪ KotlinExtensionGenerator.kt ◦
Android ▪ AndroidReaderGenerator.kt ▪ AndroidParserGenerator.kt ▪ AndroidExtensionGenerator.kt Annotation Processor 27
• Processor 給的 javax.lang.model.element.Element ◦ 包含的節點資訊 ▪ Name ▪ Annotation
▪ 鄰居節點資訊 ▪ Type ▪ Tag 資訊 (tag, attribute, value 等) Annotation Processor 28
• 我們處理節點資訊的步驟 a. 從 Element 獲取資訊 b. 預處理節點資訊 c. 產生
Kotlin 檔案 Get Data from Element Pre-process Data Generate Kotlin files Annotation Processor 29
• 接著就可以開始用 Kotlin Poet 產生檔案了! Annotation Processor 30
• 很多種方式可以發佈 ◦ bintray、gradle plugin 上 Maven Central 等等 ◦
JitPack • JitPack ◦ 不麻煩 ◦ 快 • Release 後,請一定要先試過一次 ! ◦ 不然就會遇到問題 程式碼發佈方式 31
• 使用 KSP (Kotlin Symbol Processing) 取代 KAPT ◦ 據說速度可達兩倍之快
▪ 因為 KAPT 中間會先生成 Java Stub • Kotlin Fetcher & Cache • 支援 Kotlin 跨平台 KMM 未來方向 32
• Android Weekly • Android Arsenal • 安卓開發技術週報 • 社群網站(Facebook
社團) • 技術分享 Meetup 宣傳管道 33
謝謝大家! 34 KtRssReader KtRssReader