Kotlin入門(33)運用擴展屬性

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

進行App開發的時候,使用震動器要在AndroidManifest.xml中加上如下許可權: 讓手機震動的功能用到了震動器Vibrator類,而震動器對象從系統服務VIBRATOR_SERVICE獲得,實現該功能的代碼很簡單,即便用Java書寫也只有以下兩行代碼: 兩行代碼看起來真沒什麼好簡化的了,因 ...


進行App開發的時候,使用震動器要在AndroidManifest.xml中加上如下許可權:

    <!-- 震動 -->
    <uses-permission android:name="android.permission.VIBRATE" />

 

讓手機震動的功能用到了震動器Vibrator類,而震動器對象從系統服務VIBRATOR_SERVICE獲得,實現該功能的代碼很簡單,即便用Java書寫也只有以下兩行代碼:

    Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    vibrator.vibrate(3000);

 

兩行代碼看起來真沒什麼好簡化的了,因為轉換成Kotlin也要下麵的兩行代碼:

    //常規做法:從系統服務中獲取震動器對象
    val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    vibrator.vibrate(3000)

 

雖然獲取震動器的代碼並不多,但是這真的真的很難記憶,首先開發者要調用getSystemService一把,接著絞盡腦汁才能想起該服務的名稱是VIBRATOR_SERVICE,最後再強制將類型轉換為Vibrator。其中又是大寫子母又是小寫字母還有大小寫混合,對於英文不溜的朋友來說,這簡直是個災難。如果只要一個琅琅上口的單詞就能代表震動器,那勢必為開發者省去了背誦專業英語單詞的麻煩。然而兩行代碼還能怎麼優化?倘若改造成工具類獲取震動器對象,也不見得一定省事。
不過Kotlin可不會善罷甘休,相反是迎難而上,因為它坐擁擴展函數這個法寶,之前我們多次見識了擴展函數的威力,比如提示窗的toast、提醒對話框的alert等等。當然獲取震動器對象也能按照擴展函數來改造,比如給Context添加一個擴展函數getVibrator,則該擴展函數的Kotlin代碼示例如下:

//獲取震動器
fun Context.getVibrator() : Vibrator {
    return getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
}

接著回到Activity頁面代碼,實現震動功能只需下麵的一行代碼了:

    //利用擴展函數獲得震動器對象
    getVibrator().vibrate(3000)

 

以上代碼固然簡化了,卻仍然不是最簡單的寫法,看看getVibrator()方法,前面有get後面有括弧,都是礙手礙腳的家伙。可去掉括弧就不是函數了,而變成了屬性,難不成Kotlin啥時多了個擴展屬性的用法?其實Kotlin還真的可以實現擴展屬性的功能,關鍵是要利用擴展函數進行移花接木,只要在kt文件中聲明一個Context類的新屬性,同時定義該屬性的get方法(get方法為擴展函數)。如此一來,外部訪問該擴展屬性之時,編譯器會自動調用該屬性的get方法,從而通過擴展函數間接實現了擴展屬性。接下來依舊以震動器為例,看看如何使用Kotlin代碼聲明擴展屬性vibrator:

//獲取震動器
//利用擴展函數實現擴展屬性,在Activity代碼中即可直接使用vibrator
val Context.vibrator : Vibrator
        get() = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator

 

現在回到Activity代碼,如下所示只要通過vibrator就能訪問震動器的方法了:

    //利用擴展函數實現擴展屬性,直接使用vibrator即可指代震動器對象
    vibrator.vibrate(3000)

 

當然要想正常訪問自定義的擴展函數和擴展屬性,需要在活動代碼頭部加上以下的導入語句:

import com.example.custom.util.vibrator

  

除了震動器之外,其它從系統服務獲得對象的管理器也能照此辦理,譬如通知管理器NotificationManager,按照之前的調用方式是下麵的Kotlin代碼:

    val notifyMgr = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    notifyMgr.notify(R.string.app_name, notify)

 

顯然通知管理器對象的獲取代碼更冗長,接下來將其改造為擴展屬性的方式,則相應的Context擴展代碼如下所示:

//獲取通知管理器
//試試在Activity代碼中調用“notifier.notify(R.string.app_name, notify)”
val Context.notifier: NotificationManager
    get() = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

 

然後原來通知管理器的兩行代碼便縮減為下麵的一行代碼了:

    notifier.notify(R.string.app_name, notify)

  

舉一反三,剩下的來自系統服務的管理器統統運用擴展屬性,能夠更好地方便將來的開發工作。下麵是幾個常用管理器的擴展屬性實現代碼例子:

//獲取下載管理器
val Context.downloader: DownloadManager
    get() = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
//獲取定位管理器
val Context.locator: LocationManager
    get() = getSystemService(Context.LOCATION_SERVICE) as LocationManager
//獲取連接管理器
val Context.connector: ConnectivityManager
    get() = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
//獲取電話管理器
val Context.telephone: TelephonyManager
    get() = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
//獲取無線管理器
val Context.wifi: WifiManager
    get() = getSystemService(Context.WIFI_SERVICE) as WifiManager
//獲取鬧鐘管理器
val Context.alarm: AlarmManager
    get() = getSystemService(Context.ALARM_SERVICE) as AlarmManager
//獲取音頻管理器
val Context.audio: AudioManager
    get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager

  


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

-Advertisement-
Play Games
更多相關文章
  • 一.概述 跳躍表(skiplist)是一種有序數據結構,它通過在每個節點中維持多個指向其他節點的指針,從而達到快速訪問節點的目的。在大部分情況下,跳躍表的效率可以和平衡樹(關係型資料庫的索引就是平衡樹結構)相媲美,並且因為跳躍表的實現比平衡樹要來得更為簡單,所以有不少程式使用跳躍表來代替平衡樹。 R ...
  • 簡介 reids,由Salvatore Sanfilippo寫的一個高性能的key-value資料庫,並且它是非關係型資料庫,也就是沒有像mysql那樣多錶鏈接操作,並且它是是完全開源免費的,遵守BSD協議。 ...
  • 一個孩子只有一個媽媽,而一個媽媽可以有多個孩子,這是典型的一對多的關係,這裡採用navicat圖形化界面建立二者的關係。 第一步:創建mother表,如下圖: 第二步:創建children表,在children表中創建一個外鍵ch_mom_id,如下圖: 第三步:在children表中添加外鍵約束 ...
  • redis過期時間 1.redis過期時間介紹 有時候我們並不希望redis的key一直存在。例如緩存,驗證碼等數據,我們希望它們能在一定時間內自動的被銷毀。redis提供了一些命令,能夠讓我們對key設置過期時間,並且讓key過期之後被自動刪除。 2.redis過期時間相關命令 1.EXPIRE ...
  • #*.rpm介紹 大多數二進位rpm包都包含在名稱中倒數第二個欄位中編譯rpm的體繫結構。.rpm軟體包有那麼幾種 *.src.rpm 源程式包,要先通過編譯才能安裝 *.noarch.rpm 該包適用於任何架構 *.i*86.rpm 該包適用於intel cpu的電腦上運行 *.amd64.rpm ...
  • 簡單的用set或者declare語句定義變數,然後直接作為sql的表名是不行的,mysql會把變數名當作表名。在其他的sql資料庫中也是如此,mssql的解決方法是將整條sql語句作為變數,其中穿插變數作為表名,然後用sp_executesql調用該語句。 這在mysql5.0之前是不行的,5.0之 ...
  • 因為大數據前景好,薪資高,很多人想通過參加學習大數據,然後進入大數據行業發展。但是因為大數據的門檻較高,對於學習人員有一定的要求,那麼學習大數據需要什麼基礎知識呢? 一起來瞭解下對於大數據學習者本身的學歷水平的要求。 目前大多數的機構,對於大數據學習者要求必須是大專學歷以上,而且大專學歷還要求是理工 ...
  • 轉載請標明出處:https://www.cnblogs.com/tangZH/p/9939655.html 1、同個文件夾訪問 D:\Java\main\A.java D:\Java\main\B.java A訪問B的相對路徑為B.java 2、目標文件在其子目錄 D:\Java\A.java D: ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...