為什麼要用Kotlin,和Java完全相容,相互之間引用完全不是問題,所有沒有什麼負擔。 使用Kotlin已經近一個月,基本上看完了語法就上正式項目了,期間幾次準備放棄,最終堅持下來了。關於Kotlin的優點,不必多說了,基於這一個月的經驗,來說說Kotlin的入門和坑。 配置工程 添加依賴 作為一 ...
為什麼要用Kotlin,和Java完全相容,相互之間引用完全不是問題,所有沒有什麼負擔。
使用Kotlin已經近一個月,基本上看完了語法就上正式項目了,期間幾次準備放棄,最終堅持下來了。關於Kotlin的優點,不必多說了,基於這一個月的經驗,來說說Kotlin的入門和坑。
配置工程
添加依賴
作為一個Android碼農,使用Kotlin很簡單,首先在Android Studio中安裝Kotlin插件,在Browse repositories中搜索Kotlin,安裝人數最多的那個就是。
安裝完成之後,連續按4下shift鍵,輸入config kotlin 進行搜索,選擇Config Kotlin in Project,選擇Android Gradle,選擇app module,工程就配置完成。
轉換Java到Kotlin
連續按4下shift鍵,輸入Convert Java Files 進行搜索,選擇Convert Java Files to Kotlin Files,可以自動將Java轉換為Kotlin
入門
變數聲明
- var 可變變數
- val 不可變變數
聲明變數的格式
var str: String
Kotlin不允許聲明變數但不初始化,以String為例,以下三種初始化方式
賦非空值
var str: String = ""
設為null
var str: String? = null
強制設為null
var str: String = null!!
Kotlin是空安全的,但是第三種是例外情況,如果給一個變數賦值為null!!,那麼就等於聲明這個變數不是空安全的,就算這樣使用
var str:String = null!!
str.length
編譯器也不會報錯
第一種方式,賦值之後不能將str設為null或其他String?的值,否則編譯器會報錯,第二種方式,每次使用時必須要進行檢查,直接使用的話編譯器會報錯,這樣就保證了空安全。舉個例子:
var str: String = ""
// str 不是空的,可以直接使用不必檢查是否為空
// 可以隨意給str賦非空值
str = "hello kotlin"
// 這樣編譯器是會報錯的
str = null
// 如果強制設為null,str就不再是空安全的,編譯也就不會檢查str了
str = null!!
// 聲明str2為可空的變數,str2也是空安全的
var str2: String? = null
// 直接使用str2編譯器會報錯
str2.length
// 可以這樣用
str2?.let {
log(str2)
}
// str2賦值給str也會報錯
最後達到的目的就是,使用一個空變數會報錯,使用一個可能為空的變數不檢查也會報錯,如果覺的檢查是否為空太麻煩了,Kotlin支持
if (result?.data?.item?.name != null) {
log(result?.data?.item?.name)
}
lamda
神奇的it
Kotlin的lamda表達式很簡潔,設置OnClickListener
textView.setOnClickListener {
view -> openActivity(view.context)
}
只有一個參數的時候,是可以隱藏的,用it
textView.setOnClickListener {
openActivity(it.context)
}
多個參數的時候
checkbox.setOnCheckedChangeListener { compoundButton, b ->
}
Kotlin的函數可以作為參數,寫callback的時候,可以不用interface了
// 聲明一個callback
var callback: (()->Unit)? = null
// 判斷並使用
callback?.invoke()
// 想帶參數
var callback: ((str: String)->Unit)? = null
// 判斷並使用
callback?.invoke(str)
// set callback
item.callback = {
// do something
}
// 帶參數的callback
item.callback = {
doSomething(it)
}
遇到的坑
Databinding
需要在app moudle的build.gradle裡面添加
kapt {
generateStubs = true
}
dependencies {
kapt 'com.android.databinding:compiler:2.2.0-rc2'
}
2.2.0-rc2 這個版本號必須要和根目錄下的build.gradle文件內的com.android.tools.build:gradle:2.2.0-rc2 版本號一致
Dagger2
官方博客說是支持Dagger2的,但實際遇到的情況是和Databinding結合使用有問題
奇怪的報錯
使用Databinding,設置ViewModel時
cannot access class '...'. check your module classpath for missing or conflicting dependencies
應該是Kotlin的bug,只是報錯,不影響編譯,如果不希望提示錯誤,可以添加
@Suppress("MISSING_DEPENDENCY_CLASS")
編譯的時候報找不到class的問題,clean一下就好,不知道什麼原因
不知道代碼怎麼寫
Java的代碼提示很方便,setListener,基本只用輸入new,按代碼提示回車就自動完成了,匿名函數應該怎麼寫呢
textView.setOnClickListener(object: View.OnClickListener {
override fun onClick(v: View?) {
}
})
靜態變數應該怎麼寫呢
class A {
companion object {
val TAG = "classA"
}
}
// 在Java代碼中使用
A.Companion.getTAG()
怎麼從Kotlin轉為Java
兩種方法
- 打包,輸出apk,使用dex2jar將apk代碼文件提取成jar,使用jd-jui查看,將對應的代碼拷貝出來,修改,使用
- 把Kotlin文件刪掉,用Java重寫一遍