Android:從零開始打造自己的深度連結庫(三):自定義XML協議
前言
之前我們把ARouter的原理分析了一遍,如果你是剛啟動的新專案,建議立刻使用,哪天運營有這個需求了,你就可以牛逼的對他說,我早就已經做好了。
但是老專案就會有一丟丟的尷尬,所以我們要在ARouter的基礎上,獨立深度連結的功能,然後打造出加強版的深度連結庫,我起名為DeepLinkSo。
正文
回顧一下ARouter的原始碼,我們記得他使用的是自定義註解,完成路由的註冊和繫結。註解看上去高大上,但是在這裡我認為存在一個致命的短板,那就是不夠靈活 。
註解的侷限性
註解的解析是在編譯期間完成並生成原始碼,也就是說版本一經發布,註冊的路由地址就無法發生改變,例如
1、 開啟新的路由。例如個人資訊頁我們並沒有配置路由,我們就無法通過深度連結開啟這個網頁,只能修改程式碼,然後重新發布版本解決這個問題。
2、關閉某個路由,因為某些原因某個頁面要停止外部訪問,也只能修改程式碼,然後重新發布版本。
所以幾經思考,如果路由的配置檔案能夠從網上下載更新的話,是不是就能讓深度連結更佳靈活呢?
於是我選擇了使用XML。
自定義XML協議
XML協議無論在前端後端都被廣泛的使用,而且Android對XML解析的有很好的支援,複習一下XML解析的三種方式:
1、SAX解析
2、Pull解析(推薦)
3、Dom解析
Android推薦使用Pull解析,輕量快速,所以我們也選擇使用Pull解析。
首先制定好我們的XML格式:
<?xml version="1.0" encoding="utf-8"?> <DeepLinkSo> <!-- 版本號 --> <version value="1" /> <!-- 攔截器會按照配置的順序依次執行 --> <common-interceptors> <common-interceptor>com.lzp.deeplinkso.demo.interceptor.TestInterceptor</common-interceptor> </common-interceptors> <!-- 所有需要支援DeepLink的檔案列表 --> <list> <!-- 跳轉的頁面 --> <Activity> <class>com.lzp.deeplinkso.demo.MainActivity</class> <page>main</page> </Activity> <!-- 跳轉的頁面 --> <Activity> <class>com.lzp.deeplinkso.demo.TestActivity</class> <page>test</page> <!-- 需要的引數 --> <params> <key type="Long" value="userId" /> <key value="userName" /> </params> <!-- 是否跳過公共Interceptor --> <skipCommonInterceptor>true</skipCommonInterceptor> <!-- 私有攔截器 --> <!--<interceptors>--> <!--<interceptor>com.lzp.deeplinkso.demo.interceptor.TestInterceptor</interceptor>--> <!--</interceptors>--> </Activity> <!-- 自定義事件 --> <Event> <class>com.lzp.deeplinkso.demo.handler.TestEventHandler</class> <page>event</page> <params> <key value="eventId" /> </params> </Event> </list> </DeepLinkSo>
我們在XML制定了以下內容:
1、版本號。可以根據降級和升級做一些操作。
2、全域性攔截器。所有的跳轉都會經過攔截處理,我們可以在跳轉中設定跳過全域性攔截器。
3、跳轉的頁面。可以設定對應的路由地址,跳轉的引數,私有攔截器等。
4、自定義事件。設定和頁面是一樣的,只是不跳轉頁面。
這樣我們的功能已經算是很全面了,接下來我們可以通過解析XML,儲存所有的配置資訊:
class DeepLinkSoConfig { /** * 當前版本號 * *無實際作用,僅僅是為了區別xml的版本 * */ private var version = "0" internal var listener: IDeepLinkSoListener? = null /** * 儲存跳轉Activity配置項 * */ private val activityOptionMap = HashMap<String, DeepLinkSoActivityOption>() /** * 儲存自定義事件配置項 * */ private val eventOptionMap = HashMap<String, DeepLinkSoEventOption>() /** * 自定義攔截器 * */ internal var interceptors: ArrayList<IDeepLinkSoInterceptor>? = null internal fun setVersionCode(version: String) { this.version = version } fun getVersionCode() = this.version /** *新增配置項 * */ internal fun addOption(key: String, option: DeepLinkSoOption) { when (option) { is DeepLinkSoActivityOption -> activityOptionMap[key] = option is DeepLinkSoEventOption -> eventOptionMap[key] = option } } /** *新增配置項 * */ internal fun getOption(key: String): DeepLinkSoOption? { return activityOptionMap[key] ?: eventOptionMap[key] } /** *獲取Activity配置項 * */ internal fun getActivityOption(key: String) = activityOptionMap[key] /** *獲取Event配置項 * */ internal fun getEventOption(key: String) = eventOptionMap[key] /** * 清除配置項 * */ internal fun reset() { activityOptionMap.clear() eventOptionMap.clear() interceptors?.clear() } }
解析的過程就不貼了,到此為止,我們已經為具體的開發做好了準備。
總結
今天我們分析了並制定了深度連結庫的XML協議,思考了使用註解和XML的優劣點,為之後的功能開發做好準備。
下一篇:Android:從零開始打造自己的深度連結庫(四):DeepLinkSo實戰