1. 程式人生 > >Kotlin入門(33)運用擴展屬性

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

連接 ani 例如 java mman () 記憶 常用 定位管理器

進行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

  

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