iT邦幫忙

2021 iThome 鐵人賽

DAY 1
0

為什麼會想研究 Annotation Processor ?

在去年的時候,好像 podcast 特別的夯,就想跟一群朋友玩玩看 podcast 的資料,看能不能玩出什麼東西。然後我們就發現了 podcast 的資料格式真的滿複雜的,而且各家平台的資料格式又有點不太一樣,像是有 RSS 2.0 的標準格式、google play 平台格式iTunes 的格式 等。更不用說有一些 RSS 會塞一些自定義的 tag 或 attribute ,自己程式來處理這種東西,通常格式一修改,或是 attribute 換個位置,程式就要修改,但程式碼就只是換個地方寫來處理差不多的格式。

舉例來說,以下是 RSS 2.0 的格式:

<?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>

然後我們從 iTunes 有可能拿到長這樣的格式:

<?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:image 的 tag ,這個就是 iTunes 的平台格式。

那如果我們又加上 google play 的格式,就會長這樣:

<?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>

看到這裡你可能會想說,那有什麼難的?我就 <image><itunes:image><googleplay:image> 這個三個 tag 都 parse 一遍就好了?對,如果今天只有一個 tag 要 parse 的話,我覺得這樣應該沒問題。

但仔細想想,現在出現的格式有:

  1. <googleplay:image href="http://channel.image" />
  2. <itunes:image href="https://channel.image" />
  3. 第三個和上面兩個完全不同的結構:
<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>

好,這根本大亂鬥吧! ?

我們來思考一下目前的問題有:

  • 每個 tag 內含的結構和資訊不一定一樣
  • 同樣是讀取 image url 的值,有可能會有不同的讀取順序

如果有很多這種的格式要取值,而且還有取值優先權和格式結構不同的問題時,這樣就要寫很多類似的程式碼去做一樣的事情。同樣是取 image url 的值,我想要先取 google play 的值,再取 iTunes 的,前面兩個都沒有的時候,再用 RSS 2.0 的值,而 RSS 2.0 的 url 又擺在更裡面一層的結構裡。如此一來,我們自己寫程式去 parse 這些資料會變的很繁瑣。在 podcast 格式中,image 這個 tag 只是冰山一角,要有效率地處理不同格式的問題,我們就要借助 custom annotation 和 annotation processor 的力量。

後來,我們就針對了這個 RSS 格式寫了一個 KtRssReader 的 library 專門幫助大家去讀取 RSS 資料。這個系列的文章就是在講述寫這個 library 的原理、實作和測試的心路歷程,同時,我們也會提到新的 KSP 技術和它可以怎麼改進我們 library 。如果你不熟 annotation 或者 annotation processor 的話也不用擔心,這個系列會一步一步帶你了解和實作 annotation processor 。這個 library 是使用 Kotlin 開發的,所以本系列文章的程式碼範例都會使用 Kotlin 進行解說。


下一篇
XML Parsers
系列文
如何使用 Kotlin Annotation Processor 做出自己的 Custom Data Parser Library30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言