iT邦幫忙

2022 iThome 鐵人賽

DAY 30
0
Mobile Development

從開發瀏覽器 APP 學習 Android 實戰技巧,並搭上 Jetpack Compose 的列車系列 第 31

[Day30] 從開發瀏覽器 APP 學習實戰技巧 -- 總結 & SharedPreferences

  • 分享至 

  • xImage
  •  

三十天一下子就過了,終於來到鐵人賽的尾聲。

這次除了介紹許多 EinkBro 中更好用的功能的實作方式外,還加入了不少跟開發 Android app 有關的主題:像是 Github Copilot 的使用感想,如何撰寫並上架 Android Studio Plugin,還有怎麼樣有效利用 Github Actions 來幫你完成部分的 CI/CD。有些原先打算要寫的內容,像是因為時間不夠,以及自己還不是那麼了解的情況下,只能忍痛割捨。希望以後有機會可以補齊。

希望這些內容可以讓大家在閱讀之餘,能夠激發出不同的想法和應用;或是,也一起來加入 EinkBro 的開發行列,讓電子紙閱讀器上的網頁瀏覽體驗能更加完善。

心得

最後,來說點心得。今年是第二次參加,在內容的編排上比較有餘裕,攤開這一年度的開發過程記錄來看後,針對裡頭比較多內容或是比較複雜的部份,會試著拆分成兩三天的份量來撰寫,避免一次內容太多,累了自己也苦了讀者。畢竟,太大口的食物,再好吃也都會難以下嚥或是無法細細品嚐其味道。

除了改善對於篇幅長短的掌控外,也試著穿插一些不同的主題,讓 30 天的內容不會太過死板,全是在看程式碼。要打造出一個好的 App, 寫新功能固然重要,但舉凡採用的架構,開發的環境,發布的方式等各種內外在的因素,也都有很直接的影響力。在大公司裡,這些事情可能會分工給其他的工程師處理,但是是自己的 App 的話,凡事都要自己來,多學點知識總是好的。

關於鐵人賽的發文編輯介面,感覺跟去年長得一模一樣。不好用的地方,還是一樣不好用。最讓我頭疼的一點是:上傳圖片的步驟過於繁瑣。技術文章如果要解釋一些比較難懂的概念時,用圖總是會比寫一堆文字來得好懂。但如果發文編輯介面不好用的話,就比較容易讓人懶得發圖片。

今年在寫到最後幾篇時,終於在 iT邦幫忙 中找到一篇文章,裡頭有人開發了 Chrome 的 script 讓這件事可以更像是 Web 2.0 的上傳圖片方式:IT鐵人賽小工具 : Ctrl + V 自動上傳圖片功能。之後如果還要再報名的話,應該可以省下大量上傳圖片的時間。

One More Thing: Preferences

原本想說寫寫心得做為總結就好,但,全是文字的文章不大符合鐵人賽的風格,所以我在這邊還是再分享一個開發時的小技巧。

當 App 大到一定程度時,一定會有很多設定可以讓使用者自行調整,並且會存到 SharedPreferences 中。App 裡頭都會建立專門處理 Preferences 的類別。這個類別會負責每個 Boolean, Int, String 等不同型式的選項讀取跟儲存。

舉兩個簡單的例子,如果我需要一個設定值來儲存工具列是不是要顯示在畫面上方(安裝完後,預設是在畫面下方),可以用下面的方式實作:

private val sp: SharedPreferences

var isToolbarOnTop: Boolean
    get() = sp.getBoolean(K_TOOLBAR_TOP, false)
    set(value) {
        sp.edit { putBoolean(K_TOOLBAR_TOP, value) }
    }

如果我想儲存是不是啟用多指觸控的手勢操作時,可以用下面的方式實作:

var isMultitouchEnabled: Boolean
    get() = sp.getBoolean(K_MULTITOUCH, false)
    set(value) {
        sp.edit { putBoolean(K_MULTITOUCH, value) }
    }

從上面兩個例子看得出來,雖然每一個實作都很好懂,行數也不多;但是其實除了變數名稱和 preference key const value 之外,全是重覆的程式碼。只有兩三個時,看起來還好,十個之內也勉強能接受;但如果是二三十個變數,甚至是更多,整個檔案就會充滿重覆的程式碼;在找尋某個變數時,也很難一眼掃過去就找到。

那麼,我們可以怎麼改寫這個寫法呢?首先,要建立一個繼承自 ReadWriteProperty 的類別: BooleanPreference ,裡頭包含兩個函式 getValue()setValue,分別去處理原先程式碼實作的讀和寫。

ReadWriteProperty 在官網上有解釋如下:

Base interface that can be used for implementing property delegates of read-write properties.

恰好適合拿來讀取 SharedPreferences 中的值,和在 setValue() 時把值再寫回 SharedPreferences

class BooleanPreference(
    private val sharedPreferences: SharedPreferences,
    private val key: String,
    private val defaultValue: Boolean = false
) : ReadWriteProperty<Any, Boolean> {

    override fun getValue(thisRef: Any, property: KProperty<*>): Boolean =
        sharedPreferences.getBoolean(key, defaultValue)

    override fun setValue(thisRef: Any, property: KProperty<*>, value: Boolean) =
        sharedPreferences.edit() { putBoolean(key, value) }

    // 用來切換 Boolean 值,讓程式碼看起來簡潔一點
    fun toggle() = sharedPreferences.edit() {
        putBoolean(key, !sharedPreferences.getBoolean(key, defaultValue))
    }   
}

再來就是將原先的程式碼改成下面的實作:

var isToolbarOnTop by BooleanPreference(sp, K_TOOLBAR_TOP, false)
var isMultitouchEnabled by BooleanPreference(sp, K_MULTITOUCH, false)

從 8 行變成 2 行,而且每一行的開頭都是變數名稱。這麼一來,在找變數時,或是要維護 sharedpreferences 相關實作時,是不是變得簡潔許多呢?

那麼,我們下次見囉!(明年?)

相關連結

修改 Preference 的 Commit

EinkBro 使用教學

這裡附上 EinkBro APP 基本使用教學。這一兩年來加入的功能相當地多,很多都是藏在一般使用者比較不會發現的地方,所以後來有寫了篇文章好好地說明一下。如果你沒有興趣開發,但對於使用一款極輕量又完全不受追蹤的瀏覽器有興趣的話,也可以從 Google Play Store 上下載下來試用看看喔!

全系列相關連結


上一篇
[Day29] 從開發瀏覽器 APP 學習實戰技巧 -- 追蹤碼退散!享受不受監視的瀏覽體驗
系列文
從開發瀏覽器 APP 學習 Android 實戰技巧,並搭上 Jetpack Compose 的列車31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言