ADeveloperH Blog

Meet a better self !

Android 周边技术分享


Kotlin 项目(二)

1 常见问题

1.1 please select android sdk

问题描述:提示选择 sdk 版本,但是已经配置 sdk。as 清理缓存、clean 都不行,external libraries 中没有 Android API 只有一个 Kotlin SDK

解决方案:在主 module 下 app.iml 中替换如下:

<orderEntry type="jdk" jdkName="Kotlin SDK" jdkType="KotlinSDK" />

替换为:

<orderEntry type="jdk" jdkName="Android API 27 Platform" jdkType="Android SDK" />

参考: please select android sdk(出现小红叉)

1.2 如何查看 kotlin 编译后的 java 代码

研究学习Kotlin的一些方法

How to show Java equivalent for Kotlin code

2 知识点

2.1 lateinit 和 by lazy

Kotlin lateinit 和 by lazy

让你的 Kotlin 代码远离 !!

2.2 operator 操作符重载

操作符重载

关键字与操作符

2.3 inline 内联函数的使用

内联函数

应用场景如下:


内联函数与普通的函数有点不同。一个内联函数会在编译的时候被替换
掉,而不是真正的方法调用。这在一些情况下可以减少内存分配和运行时
开销。举个例子,如果我们有一个函数,只接收一个函数作为它的参数。
如果是一个普通的函数,内部会创建一个含有那个函数的对象。另一方
面,内联函数会把我们调用这个函数的地方替换掉,所以它不需要为此生
成一个内部的对象。
如:我们可以创建代码块只提供 Lollipop 或者更高版本来执行:

inline fun supportsLollipop(code: () -> Unit){
				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)	{
								code()
				}
}
它只是检查版本,然后如果满足条件则去执行。现在我们可以这么做:
supportsLollipop{
				window.setStatusBarColor(Color.BLACK)
}
举个例子,Anko也是基于这个思想来实现	 Android	Layout		 DSL	化。你也可
以查看	 Kotlin	reference		使用DSL来编写HTML	的一个例子。

2.4 委托属性

我们可能需要一个属性具有一些相同的行为,使用 lazy 或者 observable 可以被很有趣地实现重用。而不是一次又一次地去声明那些相同的代码,Kotlin 提供了一个委托属性到一个类的方法。这就是我们知道的委托属性 。当我们使用属性 get 或者 set的时候,属性委托的 getValue 和 setValue 就会被调用。 属性委托的结构如下:

class Delegate<T> : ReadWriteProperty<Any?, T> {
    fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return    ...
    }

    fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        ...
    }
}

这个T是委托属性的类型。 getValue 函数接收一个类的引用和一个属性的元数据。
setValue 函数又接收了一个被设置的值。如果这个属性是不可修改(val),就会只有一个 getValue 函数。
下面展示属性委托是怎么设置的:

class Example {
    var p: String by Delegate()
}

它使用了 by 这个关键字来指定一个委托对象。

Kotlin 标准委托 lazy

Lazy
它包含一个lambda,当第一次执行 getValue 的时候这个lambda会被调用,所以
这个属性可以被延迟初始化。之后的调用都只会返回同一个值。这是非常有趣的特
性,	当我们在它们第一次真正调用之前不是必须需要它们的时候。我们可以节省内
存,在这些属性真正需要前不进行初始化。
class App : Application() {
    val database: SQLiteOpenHelper by lazy {
        MyDatabaseHelper(applicationContext)
    }

    override fun onCreate() {
        super.onCreate()
        val db = database.writableDatabase
    }
}
在这个例子中,database并没有被真正初始化,直到第一次调用 onCreate 时。
在那之后,我们才确保applicationContext存在,并且已经准备好可以被使用
了。lazy 操作符是线程安全的。
如果你不担心多线程问题或者想提高更多的性能,你也可以使
 lazy(LazyThreadSafeMode.NONE){	...	}

其他标准委托如:observable、vetoable、notNull 等参见 kotlin-for-android-developers

2.5 Lambda 相关

函数

高阶函数与 lambda 表达式

3 扩展知识

3.1 AnKo 的使用

Github 官网

3.2 动态代理、静态代理、CGLIB 动态代理

最近的文章

Android 适配相关

1 Android Icon 设置Android应用图标微技巧,8.0系统中应用图标的适配Android O 新特性介绍:自适应图标(Adaptive Icons) [Android O 自适应图标的意义何在?Google 设计师给你答案 科普](https://sspai.com/post/40230) Android Asset Studio使用 Image Asset Studio 创建应用图标(官网)图标在线生成工具Android Asse...…

继续阅读
更早的文章

Postman 使用

参考资料官网Postman教程——发送第一个请求(系列文章)…

继续阅读