此文章主要寫了我在學習kotlin的歷程中的一些感悟和體會。供入門的同學參考。
一、Kotlin優點
- 1.擴展函數
- 2.可空性(避免空指針)
- 3.代碼簡潔,可讀性強
- 4.高度互操作性(Kotlin與Java混合編程)
- 5.函數式編程
1.擴展函數
我們可以給任何類添加函數,而不需要繼承它
例如:給View函數添加擴展函數,控制View的可見性
view的可見性我們一般寫成
我們可以通過擴展函數來定義方法
現在我們就能直接通過調用方法來控制視圖的可見性
并且,我們在Java中也可以調用在Kotlin中定義的擴展函數。
擴展函數的本質是靜態函數,它把調用對象當做它的第一個參數
所以,如果剛剛我們的View擴展函數定義在ViewUtils.kt
文件中
那么,我們在Java
文件中可以這樣調用
ViewUtilsKt.visiable(tbCommonRlSync)
2.可空性
可空性是Kotlin類型系統中幫助你避免NullPointException錯誤的特性。
Kotlin的變量類型包括可空類型和非空類型。可空類型在編譯期會檢查Null情況
Kotlin中提供多種運算符,幫助我們檢查可空類型變量的Null情況
- 安全調用運算符
?.
- Elvis運算符
?:
- 安全轉換運算符
as?
- 非空斷言
!!
-
let
函數
3.代碼簡潔,可讀性強
例如:創建一個對象
Java中的寫法
在kotlin文件中
再例如:我們在定義按鈕點擊事件時通常的寫法是
Button button = (Button)findViewById(R.id.button)
button.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
Toast.makeText(this,”Click The Button",Toast.LENGTH_SHORT);
}
});
而利用Kotlin+Extension+Anko可以簡化為
button.onClick{
toast(“Click The Button”);
}
4.與Java的互操作性
Kotlin與Java能夠進行混合編程,在原有Java項目中使用Kotlin編程時,不需要將整個項目都轉成Kotlin。
(1)屬性讀寫
Kotlin可以自動識別Java中的getter/setter;在Java中可以過getter/setter操作Kotlin的屬性。
(2)關鍵字調用
Kotlin中定義的一些關鍵字是Java中沒有的,如果Java中使用這些關鍵字作為方法名,那么在Kotlin中調用時,要加入轉義字符。如is關鍵字:
(3)平臺類型
Java 中的任何引用都可能是
null
,這使得 Kotlin 對來自 Java 的對象要求嚴格空安全是不現實的。 Java 聲明的類型在 Kotlin 中會被特別對待并稱為平臺類型。對這種類型的空檢查會放寬, 因此它們的安全保證與在 Java 中相同。當我們調用平臺類型變量的方法時,Kotlin 不會在編譯時報告可空性錯誤, 但在運行時調用可能會失敗,因為空指針異常或者 Kotlin 生成的阻止空值傳播的斷言:
平臺類型表示法
用助記符!來表示平臺類型,如:
T!
表示T
或者T?
(4)可變參數
Kotlin調用Java中含有可變參數的函數時,可以用展開運算符*
例如:在Java中定義方法
public void removeIndicesVarArg(int... indices)
在kotlin中調用就要用到展開運算符
javaObj.removeIndicesVarArg(*array)
5.函數式編程
Kotlin支持面向對象和函數式兩種編程風格。
函數式編程的核心是
- 頭等函數——把函數當作值來使用,可以用變量來保存它,把它當作參數傳遞,或者當作其他函數的返回值。
- 不可變性——使用不可變對象,保證他們的狀態在創建之后不能再變化
- 無副作用——使用的是純函數。此函數在輸入相同時會產生同樣的結果,并且不會修改其他對象的狀態,也不會與外面的世界交互。
二、學習歷程
1.技術背景
書籍
- kotlin in action(1-2周)
主要講解Kotlin的入門基礎,推薦指數五顆星 - kotlin-for-android-developers-zh(2天)
主要講解kotlin的實踐,對基礎知識沒有過多的講解,推薦指數四顆星 - kotlin崛起:次世代Android開發(1天)
主要看的是Anko Layout DSL部分,推薦指數三顆星 - kotlin-reference-chinese (http://www.kotlincn.net/docs/reference/) (1天)
kotlin的官方文檔,主要看的是java與kotlin的互操作性,推薦指數五顆星
2.遇到過的問題
(1) kotlin中使用Retrofit的通配符問題
Retrofit請求的時候,要先定義一個接口
在Java中 代碼可以正常執行
在kotlin中代碼不能正常執行
Retrofit在執行此方法時,會檢查參數的類型。雖然kotlin的Any類似于Java的Object,但是這里的會被編譯成通配符?。Retrofit檢查到類型為通配符,會報出異常,導致代碼不能正確的執行。
這時候我們可以添加@JvmSuppressWildcards
注解
@JvmSuppressWildcards
用來注解類和方法,使得被標記元素的泛型參數不會被編譯成通配符。這樣就可以保證代碼正常執行
(2)數據庫框架GreenDao
,需要在實體類中添加注解生成對應的Dao類
但是這個框架并不支持Kotlin的實體類,所以在使用的時候,我們還是要將需要保存到數據庫的實體,以Java類的形式編寫。
(3)java調用Kotlin代碼時,可能會傳入一個空的變量,由于是平臺類型的變量在編譯的時候并不會報錯,但是在運行期間會直接奔潰。故我們在使用平臺類型的時候,要謹慎使用。
(4)kotlin與Databinding一起使用的話
需要在Gradle
文件中添加如下配置
kapt {
generateStubs = true
}
dependencies {
kapt 'com.android.databinding:compiler:3.0.0'
}
三、Kotlin實踐
利用kotlin來編寫一個小demo
功能簡介
- 利用kotlin來編寫一個小Demo,實現簡單的登錄功能和地區信息的增刪查改
- 利用
Anko Layout DSL
來替代XML文件編寫界面 - 使用
Extension
來訪問組件 - 使用擴展函數作為工具類
- 以
rxJava
+Retrofit
作為網絡框架,GreenDao
作為數據庫操作框架
1.登錄界面(Anko layout dsl)
編寫如圖一個登錄界面
用Anko Layout DSL來寫的話
- 其中
dip
函數是Anko庫中將dip
單位的值轉為像素單位的一個函數 -
onClick
函數是Anko庫中對OnClickListener
接口的一個擴展函數
2.區域列表界面
編寫如圖一個區域列表界面
用Anko Layout DSL來寫的話
Anko Layout DSL優缺點
- 優點:
1.相比于Java代碼編寫的界面,更加的簡潔。所有的組件都是Anko庫中定義的擴展函數,lambda表達式作為參數,可讀性強
2.相比較與XML文件,這種編寫界面的方式更易于擴展,代碼易于重用 - 缺點:
1.現階段的Anko Layout Preview
工具還不太成熟,預覽界面不能實時刷新。
2.組件Id
需要自己定義,通過Id
獲取組件很麻煩,也沒辦法與Extension
一起使用
下面看下Extension的使用
3.用Extension來訪問XML中的組件
先用XML編寫一個Dialog彈窗,如圖
XML文件如下
我們在Kotlin文件中,導入該布局
就能直接利用Id訪問組件
這樣我們就能擺脫大量的findViewById
代碼
4.非空性
-
let
函數 保證接收到的參數為空時,不執行任何操作
5.擴展函數
為Activity定義擴展函數,用于添加Fragment
在Activity中可以直接使用addFrg添加Fragment
6.函數式編程
這里將接口返回的List做適當的處理,用asSequence將數組轉換成序列的形式
filter
函數主要是從集合中移除不想要的元素
map
函數主要是 對集合中每一個元素應用給定的函數并把結果收集到一個新的集合
apply
函數是把第一個參數轉換成第二個參數傳給它的lambda
接收者,并返回作為實參傳遞給它的對象。
最后用toList
函數將序列轉換為數組。
總結
- Kotlin編程使我們的代碼變得更加簡潔,可讀性強,便于我們代碼的review
- 可空性的處理極大的減少了我們代碼中NPE的風險
- 擴展函數的存在,讓我們能夠方便的擴展API
- kotlin與Java高度的互操作性使我們可以在原有的項目中輕松的使用Kotlin
- Kotlin中大量的庫函數,極大的減少了我們的工具類