前言

为什麽会想研究 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 进行解说。


<<:  (),[] -- 列表与元组

>>:  Day6 - 程序设计报价 (ㄧ)- 报价单的 Bug

【LeetCode】Monotonic Stack

monotonic :单调,递增或递减 这是一个看起来很简单的资料结构, 拥有 O(N) time ...

[ 卡卡 DAY 8 ] - React Native 跨平台装置判断

还记得 React Native 可以同时完成 iOS / Android 装置吧? 跨平台装置如...

Day#04 TableView

前言 承接昨天的内容,今天来加上viewDidLoad中的逻辑内容{ @•̀ꈊ•́@ } 学习资源 ...

冒险村01 - Begin from linter(1)

01 - Begin from linter : rails_best_practices 好的开始...

Day03-开始使用Docker吧(DockerFile)

前言 今天的文章要来介绍如何产生 Docker 的映像档了,有了上一篇文章的介绍相信读者对於 Doc...