前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kotlin入门(33)运用扩展属性

Kotlin入门(33)运用扩展属性

作者头像
aqi00
发布2019-01-18 15:57:12
8580
发布2019-01-18 15:57:12
举报
文章被收录于专栏:老欧说安卓老欧说安卓

进行App开发的时候,使用震动器要在AndroidManifest.xml中加上如下权限:

代码语言:javascript
复制
    <!-- 震动 -->
    <uses-permission android:name="android.permission.VIBRATE" />

让手机震动的功能用到了震动器Vibrator类,而震动器对象从系统服务VIBRATOR_SERVICE获得,实现该功能的代码很简单,即便用Java书写也只有以下两行代码:

代码语言:javascript
复制
    Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    vibrator.vibrate(3000);

两行代码看起来真没什么好简化的了,因为转换成Kotlin也要下面的两行代码:

代码语言:javascript
复制
    //常规做法:从系统服务中获取震动器对象
    val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    vibrator.vibrate(3000)

虽然获取震动器的代码并不多,但是这真的真的很难记忆,首先开发者要调用getSystemService一把,接着绞尽脑汁才能想起该服务的名称是VIBRATOR_SERVICE,最后再强制将类型转换为Vibrator。其中又是大写子母又是小写字母还有大小写混合,对于英文不溜的朋友来说,这简直是个灾难。如果只要一个琅琅上口的单词就能代表震动器,那势必为开发者省去了背诵专业英语单词的麻烦。然而两行代码还能怎么优化?倘若改造成工具类获取震动器对象,也不见得一定省事。 不过Kotlin可不会善罢甘休,相反是迎难而上,因为它坐拥扩展函数这个法宝,之前我们多次见识了扩展函数的威力,比如提示窗的toast、提醒对话框的alert等等。当然获取震动器对象也能按照扩展函数来改造,比如给Context添加一个扩展函数getVibrator,则该扩展函数的Kotlin代码示例如下:

代码语言:javascript
复制
//获取震动器
fun Context.getVibrator() : Vibrator {
    return getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
}

接着回到Activity页面代码,实现震动功能只需下面的一行代码了:

代码语言:javascript
复制
    //利用扩展函数获得震动器对象
    getVibrator().vibrate(3000)

以上代码固然简化了,却仍然不是最简单的写法,看看getVibrator()方法,前面有get后面有括号,都是碍手碍脚的家伙。可去掉括号就不是函数了,而变成了属性,难不成Kotlin啥时多了个扩展属性的用法?其实Kotlin还真的可以实现扩展属性的功能,关键是要利用扩展函数进行移花接木,只要在kt文件中声明一个Context类的新属性,同时定义该属性的get方法(get方法为扩展函数)。如此一来,外部访问该扩展属性之时,编译器会自动调用该属性的get方法,从而通过扩展函数间接实现了扩展属性。接下来依旧以震动器为例,看看如何使用Kotlin代码声明扩展属性vibrator:

代码语言:javascript
复制
//获取震动器
//利用扩展函数实现扩展属性,在Activity代码中即可直接使用vibrator
val Context.vibrator : Vibrator
        get() = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator

现在回到Activity代码,如下所示只要通过vibrator就能访问震动器的方法了:

代码语言:javascript
复制
    //利用扩展函数实现扩展属性,直接使用vibrator即可指代震动器对象
    vibrator.vibrate(3000)

当然要想正常访问自定义的扩展函数和扩展属性,需要在活动代码头部加上以下的导入语句:

代码语言:javascript
复制
import com.example.custom.util.vibrator

除了震动器之外,其它从系统服务获得对象的管理器也能照此办理,譬如通知管理器NotificationManager,按照之前的调用方式是下面的Kotlin代码:

代码语言:javascript
复制
    val notifyMgr = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    notifyMgr.notify(R.string.app_name, notify)

显然通知管理器对象的获取代码更冗长,接下来将其改造为扩展属性的方式,则相应的Context扩展代码如下所示:

代码语言:javascript
复制
//获取通知管理器
//试试在Activity代码中调用“notifier.notify(R.string.app_name, notify)”
val Context.notifier: NotificationManager
    get() = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

然后原来通知管理器的两行代码便缩减为下面的一行代码了:

代码语言:javascript
复制
    notifier.notify(R.string.app_name, notify)

举一反三,剩下的来自系统服务的管理器统统运用扩展属性,能够更好地方便将来的开发工作。下面是几个常用管理器的扩展属性实现代码例子:

代码语言:javascript
复制
//获取下载管理器
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入门教程的完整目录

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年11月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档