在Android中,kotlin 的一些开发技巧(二)

之前在 Android中,kotlin 的一些开发技巧 中介绍了七种 Kotlin 技巧,经过一年多 kotlin 的使用,这里再介绍新的开发技巧。

中缀表达式

带有 infix 关键字的方法,可以使用中缀表示法调用。中缀表示法是指忽略该调用的点与圆括号。使用中缀表达式可以实现很多效果,如下所示:

kotlin 复制代码
// 定义支持 可null 的 > 操作
public infix fun Int?.bigger(other: Int?): Boolean {
    return when {
        this != null && other != null -> this - other > 0
        else -> false
    }
}
// 如下所示,结果为 false
val result = 5 bigger null

observable 委托

单例对象 kotlin.properties.Delegates 有一个 observable() 便利函数来创建一个 ReadWriteProperty 委托,该委托将对与其关联的变量或属性的任何修改进行拦截。当发生修改时,委托将调用你用 observable() 函数注册的事件处理程序。如下所示:

kotlin 复制代码
// 每次赋值时,自动cancel上一个旧job
inline fun <reified T : Job?> cannelJob() = Delegates.observable<T?>(initialValue = null) { property, oldValue, newValue -> 
    oldValue?.cancel() 
}
// 示例如下:
private var myJob: Job? by cannelJob()
// 会自动调用 myJob?.cancel()
myJob = scope.launch {
    ...
}

vetoable 委托

与使用 observable 注册的处理程序不同,其返回类型为Unit,使用 vetoable 注册的处理程序返回布尔结果。返回值为true表示同意接受修改,false 表示拒绝。如果拒绝,修改将被丢弃。示例如下:

kotlin 复制代码
fun main() {
    // 定义一个Person类,使用vetoable委托限制年龄范围
    class Person {
        var age: Int by Delegates.vetoable(initialValue = 0) { property, oldValue, newValue ->
            // 校验逻辑:年龄必须在0-150之间才允许修改
            newValue in 0..150
        }
    }

    val person = Person()

    // 1. 合法修改:年龄设为20,符合范围
    person.age = 20
    println("修改后的年龄:${person.age}") // 输出:修改后的年龄:20

    // 2. 非法修改:年龄设为200,超出范围,被否决
    person.age = 200
    println("修改后的年龄:${person.age}") // 输出:修改后的年龄:20(保留旧值)

    // 3. 非法修改:年龄设为-5,同样被否决
    person.age = -5
    println("修改后的年龄:${person.age}") // 输出:修改后的年龄:20(保留旧值)
}

NonCancellable

withContext (NonCancellable) 会让代码 "无视" 协程取消,应仅用于必须执行的收尾操作,代码示例如下:

scss 复制代码
val job = scope.launch {
        try {
            // 模拟建立网络连接
            socket = Socket("localhost", 8080)
            println("网络连接已建立,执行数据传输...")
            delay(10000) // 模拟数据传输(可取消)
        } finally {
            println("进入 finally 块,准备关闭连接...")
            // 必须用 NonCancellable,
            // 否则 socket.close() 若包含挂起逻辑会被取消
            withContext(NonCancellable) {
                socket?.close()
                println("网络连接已关闭")
                // 模拟挂起的收尾操作(如写入日志)
                delay(1000)
                println("收尾日志已写入")
            }
        }
    }
相关推荐
木易 士心1 小时前
MVC、MVP 与 MVVM:Android 架构演进之路
android·架构·mvc
百锦再1 小时前
国产数据库的平替亮点——关系型数据库架构适配
android·java·前端·数据库·sql·算法·数据库架构
走在路上的菜鸟2 小时前
Android学Dart学习笔记第十三节 注解
android·笔记·学习·flutter
介一安全2 小时前
【Frida Android】实战篇15:Frida检测与绕过——基于/proc/self/maps的攻防实战
android·网络安全·逆向·安全性测试·frida
hhy_smile2 小时前
Android 与 java 设计笔记
android·java·笔记
laocooon5238578863 小时前
C#二次开发中简单块的定义与应用
android·数据库·c#
似霰3 小时前
传统 Hal 开发笔记5 —— 添加硬件访问服务
android·framework·hal
恋猫de小郭3 小时前
Android 宣布 Runtime 编译速度史诗级提升:在编译时间上优化了 18%
android·前端·flutter
csj503 小时前
安卓基础之《(4)—Activity组件》
android
游戏开发爱好者83 小时前
H5 混合应用加密 Web 资源暴露到 IPA 层防护的完整技术方案
android·前端·ios·小程序·uni-app·iphone·webview