Kotlin入門(28)Application單例化

来源:https://www.cnblogs.com/aqi00/archive/2018/10/23/9837936.html
-Advertisement-
Play Games

Application是Android的又一大組件,在App運行過程中,有且僅有一個Application對象貫穿應用的整個生命周期,所以適合在Application中保存應用運行時的全局變數。而開展該工作的基礎,是必須獲得Application對象的唯一實例,也就是將Application單例化。 ...


Application是Android的又一大組件,在App運行過程中,有且僅有一個Application對象貫穿應用的整個生命周期,所以適合在Application中保存應用運行時的全局變數。而開展該工作的基礎,是必須獲得Application對象的唯一實例,也就是將Application單例化。獲取一個類的單例對象,需要運用程式設計中常見的單例模式,倘若通過Java編碼實現單例化,想必早已是大家耳熟能詳的了。下麵便是個Application單例化的Java代碼例子:

public class MainApplication extends Application {

    private static MainApplication mApp;
    
    public static MainApplication getInstance() {
        return mApp;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mApp = this;
    }
}

從上可見這個單例模式的實現過程主要有三個步驟,說明如下:

1、在自定義的Application類內部聲明一個該類的靜態實例;
2、重寫onCreate方法,把自身對象賦值給第一步聲明的實例;
3、提供一個供外部調用的靜態方法getInstance,該方法返回第一步聲明的Application類實例;
不管是代碼還是步驟,這個單例化的實現都還蠻簡單的。同樣的單例化過程通過Kotlin編碼實現的話,靜態屬性和靜態方法可利用伴生對象來實現,這樣就形成了Kotlin單例化的第一種方式:手工聲明屬性的單例化,具體描述見下。


一、手工聲明屬性的單例化
該方式與Java的常見做法一致,也是手工聲明自身類的靜態實例,然後通過靜態方法返回自身實例。與Java的不同之處在於:Kotlin引入了空安全機制,故而靜態屬性要聲明為可空變數、然後獲得實例時要在末尾加上雙感嘆號表示非空,當然也可事先將自身實例聲明為延遲初始化屬性。總之,兩種聲明手段都是為了確保一個目的,即Application類提供給外部訪問的自身實例必須是非空的。
下麵是手工單例化的Kotlin代碼例子:

class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        instance = this
    }

    //單例化的第一種方式:聲明一個簡單的Application屬性
    companion object {
        //情況一:聲明可空的屬性
        private var instance: MainApplication? = null
        fun instance() = instance!!
        //情況二:聲明延遲初始化屬性
        //private lateinit var instance: MainApplication
        //fun instance() = instance
    }
}

  

二、藉助Delegates的委托屬性單例化
第一種方式的單例化,雖然提供了兩種屬性的聲明手段,但只是為了保證自身實例的非空性。如果僅僅是確保屬性非空,其實Kotlin已經提供了一個系統工具進行自動校驗,這個工具便是Delegates的notNull方法。該方法返回非空校驗的行為,只要將指定屬性的讀寫行為委托給這個非空校驗行為,那麼開發者就無需手工進行非空判斷了。利用Delegates工具的屬性代理功能,就構成了Kotlin的第二種單例化方式;有關委托屬性和屬性代理的介紹,可參見前面的博文《Kotlin入門(25)共用參數模板》。
下麵是系統委托屬性單例化的Kotlin代碼例子:

class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        instance = this
    }

    //單例化的第二種方式:利用系統自帶的Delegates生成委托屬性
    companion object {
        private var instance: MainApplication by Delegates.notNull()
        fun instance() = instance
    }
}

第二種方式的委托屬性單例化,在App代碼中獲取Application實例與第一種方式是一樣的,都是調用“MainApplication.instance()”這個函數獲得Application的自身實例。

三、自定義委托行為的單例化
前兩種單例化都只完成了非空校驗,還不是嚴格意義上的單例化。真正的單例化是有且僅有一次賦值操作,儘管前兩種的單例化並未實現唯一賦值功能,但是在大多數場合已經夠用了。可是作為孜孜不倦的開發者,務必要究根問底,到底能不能實現唯一賦值情況下的單例化。顯然系統自帶的Delegates工具沒有提供大家期待的校驗行為,於是開發者必須自己寫一個能夠校驗賦值次數的行為類,目的是接管委托屬性的讀寫行為。自定義接管行為的實現,前面的博文《Kotlin入門(25)共用參數模板》即已給出了Preference<T>的完整源碼,其中關鍵是重寫了讀方法getValue和寫方法setValue,因此在這裡可借鑒Preference<T>完成自定義的委托行為編碼。
下麵是自定義委托行為的單例化代碼:

class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        instance = this
    }

    //單例化的第三種方式:自定義一個非空且只能一次性賦值的委托屬性
    companion object {
        private var instance: MainApplication by NotNullSingleValueVar()
        fun instance() = instance
    }

    //定義一個屬性管理類,進行非空和重覆賦值的判斷
    private class NotNullSingleValueVar<T>() : ReadWriteProperty<Any?, T> {
        private var value: T? = null
        override fun getValue(thisRef: Any?, property: KProperty<*>): T {
            return value ?: throw IllegalStateException("application not initialized")
        }

        override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
            this.value = if (this.value == null) value
            else throw IllegalStateException("application already initialized")
        }
    }
}

由上述代碼看到,自定義的委托行為在getValue方法中進行非空校驗,在setValue方法中進行重覆賦值的校驗,從而按照要求接管了委托屬性的讀寫行為。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 筆者在看了相關的教程之後發現教程當中的資源已經過時了。當我們在創建了一個新的空白的工程之後,會發現其文件夾下麵的分文件夾目錄和官方的教程文件結構完全不同,因此會引起很多誤解。筆者使用的是最新版的Android Stuidio,其目錄結構如下圖所示: 一.創建主活動(First活動) 從中我們可以得到 ...
  • 一,首先,我們在菜單欄上找到這一欄: 然後點擊build,再點擊generate apk,然後出現以下界面: 由於之前我們並沒有進行apk文件的生成,因此需要這個apk key做一個驗證,以防您的app上線之後被別人盜用,同時證明自己對這個app的擁有權。key store path就是您app k ...
  • Android json支持五種數據類型 String / int(float)/bool / null / object 今天說 object : ...
  • 歡迎大家前往 "騰訊雲+社區" ,獲取更多騰訊海量技術實踐乾貨哦~ 本文由 "elson" 發表於 "雲+社區專欄" 目前在不考慮IE以及低端安卓機(4.3 )的相容下,已經可以放心使用flex進行佈局了。什麼是flex佈局以及它的好處,這裡就不再贅述。 在這篇文章里,想說說flex佈局的屬性語法及 ...
  • 準備 工具:HBuilder 一、全屏設置,不顯示系統狀態欄 這裡所說的系統狀態欄就是包括了:信號、運營商、電量等信息手機屏幕最頂部信息。 全屏並非狀態欄透明或變色,而是沒有狀態欄,也就是看不見電量、信號那條了,部分項目需要這樣的場景。 全屏設置方法: 新建一個wap2app項目並完成各項配置後,打 ...
  • Android預設的Toast太醜了,我們來封裝一個花里胡哨的Toast吧,就叫ColoredToast。 Github:https://github.com/imcloudfloating/DesignApp 效果: Toast有一個setView方法,通過它我們可以設置自定義的佈局,這裡我只是加 ...
  • C/S架構(Client/Server,即客戶機/伺服器模式)分為客戶機和伺服器兩層:第一層是在客戶機系統上結合了表示與業務邏輯,第二層是通過網路結合了資料庫伺服器。簡單的說就是第一層是用戶表示層,第二層是資料庫層。客戶端和伺服器直接相連,這兩個組成部分都承擔著重要的角色。 Android內核是基於 ...
  • 前面已經封裝了很多常用、基礎的組件了: "base module" , 包括了: crash 處理 常用工具類 apk 升級處理 log 組件 logcat 採集 ftp 文件上傳 blur 高斯模糊 fresco 圖片處理 等等 那麼,今天繼續再來封裝一個網路組件,基於 "volley" 的二次封 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...