进行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)运用扩展属性的更多相关文章

  1. Kotlin入门教程——目录索引

    Kotlin是谷歌官方认可的Android开发语言,Android Studio从3.0版本开始就内置了Kotlin,所以未来在App开发中Kotlin取代Java是大势所趋,就像当初Android ...

  2. Kotlin(2): 优雅地扩展类的方法和属性

    欢迎Follow我的GitHub, 关注我的CSDN. 个人博客: http://www.wangchenlong.org/, 最新内容. Kotlin由JetBrains公司推出, 是兼容Java的 ...

  3. 写给Android开发者的Kotlin入门

    写给Android开发者的Kotlin入门 转 https://www.jianshu.com/p/bb53cba6c8f4 Google在今年的IO大会上宣布,将Android开发的官方语言更换为K ...

  4. Kotlin入门(11)江湖绝技之特殊函数

    上一篇文章介绍了Kotlin对函数的输入参数所做的增强之处,其实函数这块Kotlin还有好些重大改进,集中体现在几类特殊函数,比如泛型函数.内联函数.扩展函数.尾递归函数.高阶函数等等,因此本篇文章就 ...

  5. 关于ES6扩展属性

    ES6 let和const let命令 只在代码块作用域内有效 不存在变量提升(不能在申明之前赋值) 暂时性死区(在区域内不受外部变量影响) 不允许重复申明(在相同代码块区域内) 块级作用域 let为 ...

  6. Kotlin的扩展函数:扩展Android框架(KAD 08)

    作者:Antonio Leiva 时间:Jan 11, 2017 原文链接:https://antonioleiva.com/extension-functions-kotlin/ 扩展函数是Kotl ...

  7. [NewLife.XCode]扩展属性(替代多表关联Join提升性能)

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示 ...

  8. Kotlin入门(28)Application单例化

    Application是Android的又一大组件,在App运行过程中,有且仅有一个Application对象贯穿应用的整个生命周期,所以适合在Application中保存应用运行时的全局变量.而开展 ...

  9. Kotlin入门(13)类成员的众生相

    上一篇文章介绍了类的简单定义及其构造方式,当时为了方便观察演示结果,在示例代码的构造函数中直接调用toast提示方法,但实际开发是不能这么干的.合理的做法是外部访问类的成员属性或者成员方法,从而获得处 ...

随机推荐

  1. [Swift]LeetCode839. 相似字符串组 | Similar String Groups

    Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it ...

  2. [IOI2007] sails 船帆

    显然答案与杆的顺序无关(按每个高度考虑). 从高到低考虑杆,设此时的状态为\(S\),\(S[i]\)是高度\(i\)的帆的数目,初始全为\(0\),当前杆的高度为\(h\),杆上需要放置的帆的数目为 ...

  3. Python内置函数(38)——list

    英文文档: class list([iterable]) Rather than being a function, list is actually a mutable sequence type, ...

  4. webdav 概览

    webdav 概览 WebDav(Web Distributed Authoring and Versioning) 是一个控制远端Web资源的协议,它基于HTTP1.1.它的定义在RFC 4918( ...

  5. 『土地征用 Land Acquisition 斜率优化DP』

    斜率优化DP的综合运用,对斜率优化的新理解. 详细介绍见『玩具装箱TOY 斜率优化DP』 土地征用 Land Acquisition(USACO08MAR) Description Farmer Jo ...

  6. Java基础12:深入理解Class类和Object类

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

  7. 『Asp.Net 组件』Asp.Net 服务器组件 的开发优势和劣势

    在写<Asp.Net 服务器组件系列文档>之前,笔者不才,揣测微软战略用意: 微软利益诉求莫过于 微软产品和技术的市场份额: 因此,微软战略之一莫过于将 所有开发人员 团聚在 微软周围,以 ...

  8. 看板中的WIP限制

    WIP限制并不是真的要限制你的进度,事实上正相反. 什么是WIP限制? 在敏捷开发中,WIP限制决定了每种情况下的工作流中可以存续的最大工作量.限制进行中的工作数量可以更容易辨识团队工作流中的无效工作 ...

  9. Spring Boot 路由

    多路由指向同一个方法 @GetMapping(value = {"/login","/index"}) 访问http://127.0.0.1/index 和 h ...

  10. Spring Boot 项目配置的使用方法

    第一种写法resources目录下的application.properties文件 第二种写法resources目录下的application.yml文件 在项目中获取配置项: 分组配置:  (配置 ...