背景
上次我們在Android使用Kotlin初探這篇文章了解了怎么在Androiod項(xiàng)目中引入Kotlin開發(fā)夺艰。這一次我們來實(shí)際用Kotlin來開發(fā)我們的項(xiàng)目惠毁,看看使用Kotlin來開發(fā)還有什么值得注意的地方老翘。
Kotlin擴(kuò)展
剛開始接觸Android開發(fā)的時(shí)候光羞,我們肯定都有過經(jīng)常寫findViewById的經(jīng)歷逆航,然后有好多開源的框架美旧,提供了直接使用注解的方式讓我們在聲明的變量上加上id找到對應(yīng)的控件〔持停現(xiàn)在使用kotlin擴(kuò)展我們可以直接使用控件id當(dāng)做我們的控件。
1榴嗅、在app的build.gradle文件中添加Kotlin擴(kuò)展插件
apply plugin: 'kotlin-android-extensions'
2妄呕、導(dǎo)入對應(yīng)的包
//對應(yīng)容易activity或者fragment中導(dǎo)入
import kotlinx.android.synthetic.main.<布局文件>.*
//調(diào)用View的合成屬性導(dǎo)入,例如Adapter中的itemView嗽测,使用itemView.xxxView
import kotlinx.android.synthetic.main.activity_main.view.*
3绪励、使用
例如有id為hello的TextView在布局文件中,則直接使用
hello.setText("Hello World")
合成屬性论咏,讀者大可以寫一個(gè)用Kotlin寫一個(gè)Adapter优炬,然后就明白了。
itemView.hello.setText("Hello World")
Android框架
Dagger
在 Java 中需要指定 Dagger 作為 annotationProcessor(或 apt)依賴:
dependencies {
...
annotationProcessor "com.google.dagger:dagger-compiler:$dagger-version"
}
在 Kotlin 中則需要添加 kotlin-kapt 插件激活 kapt厅贪,并使用 kapt 替換 annotationProcessor:
apply plugin: 'kotlin-kapt'
dependencies {
...
kapt "com.google.dagger:dagger-compiler:$dagger-version"
}
kapt 也能夠處理 Java 文件蠢护,所以不需要再保留 annotationProcessor 的依賴。
與 Java 一樣养涮,Dagger 通過 @Inject 對構(gòu)造函數(shù)注解葵硕,進(jìn)而創(chuàng)建類的實(shí)例。 而 Kotlin 使用更簡潔的語法同時(shí)聲明屬性和構(gòu)造函數(shù)參數(shù)贯吓。 在 Kotlin 中對構(gòu)造函數(shù)進(jìn)行注解懈凹,必須顯式使用 constructor 關(guān)鍵字,并在關(guān)鍵字前聲明 @Inject悄谐。
class Thermosiphon
@Inject constructor(
private val heater: Heater
) : Pump {
// ……
}
注解方法看上去完全相同介评。 在下面的示例中,@Binds 決定了無論何時(shí)需要 Pump,使用都是 Thermosiphon 對象们陆,@Provides 指定了 Heater 的構(gòu)造方式寒瓦,@Singleton 則表示 Heater 是全局單例:
@Module
abstract class PumpModule {
@Binds
abstract fun providePump(pump: Thermosiphon): Pump
}
@Module(includes = arrayOf(PumpModule::class))
class DripCoffeeModule {
@Provides @Singleton
fun provideHeater(): Heater = ElectricHeater()
}
@Module-注解的類定義如何提供不同對象。 需要注意的是坪仇,作為多參數(shù)傳遞注解參數(shù)時(shí)杂腰,需要顯示的使用 arrayOf 進(jìn)行包裝,比如上文示例中的 @Module(includes = arrayOf(PumpModule::class))椅文。
使用 @Component 為類型生成依賴注入的實(shí)現(xiàn)喂很。 自動(dòng)生成類文件的類名帶有 Dagger 前綴,比如下文示例 DaggerCoffeeShop:
@Singleton
@Component(modules = arrayOf(DripCoffeeModule::class))
interface CoffeeShop {
fun maker(): CoffeeMaker
}
fun main(args: Array<String>) {
val coffee = DaggerCoffeeShop.builder().build()
coffee.maker().brew()
}
Dagger 為 CoffeeShop 所生成的實(shí)現(xiàn)皆刺,允許你獲得一個(gè)完全注入的 CoffeeMaker少辣。 DaggerCoffeeShop 的具體代碼實(shí)現(xiàn)可在 IDE 中查看。
DataBinding
和使用 Java 一樣羡蛾,開發(fā)者需要在 gradle 文件中添加并激活配置毒坛。
android {
...
dataBinding {
enabled = true
}
}
添加 kapt 的依賴后即可與 Kotlin 代碼交互:
apply plugin: 'kotlin-kapt'
dependencies {
kapt "com.android.databinding:compiler:$android_plugin_version"
}
具體使用不再說明,使用方式幾乎不變主要是引入需要添加的kapt
對于引入Android的開源框架林说,主要就是引入kapt,然后對于Kotlin引入對應(yīng)的框架屯伞。對于Java文件的處理腿箩,kapt可以支持,如果框架只是對Java文件的劣摇,那么之前的依賴可以省去珠移。
其他框架不在贅述,可以參考詳細(xì)的文檔末融,或者自己多試驗(yàn)钧惧。
Kotlin與Java的交互
Kotlin調(diào)用Java
Kotlin在設(shè)計(jì)的時(shí)候就考慮到了與Java的互操作性,幾乎所有的Java代碼都可以在Koltin中以Kotlin的形式進(jìn)行使用勾习。但也有要注意的地方
將-kotlin-中是關(guān)鍵字的-java-標(biāo)識(shí)符進(jìn)行轉(zhuǎn)義:
一些 Kotlin 關(guān)鍵字在 Java 中是有效標(biāo)識(shí)符:in浓瞪、 object、 is 等等巧婶。 如果一個(gè) Java 庫使用了 Kotlin 關(guān)鍵字作為方法乾颁,你仍然可以通過反引號(hào)(`)字符轉(zhuǎn)義它來調(diào)用該方法
foo.`is`(bar)
空安全和平臺(tái)類型:
Java 中的任何引用都可能是 null,這使得 Kotlin 對來自 Java 的對象要求嚴(yán)格空安全是不現(xiàn)實(shí)的艺栈。 Java 聲明的類型在 Kotlin 中會(huì)被特別對待并稱為平臺(tái)類型英岭。對這種類型的空檢查會(huì)放寬, 因此它們的安全保證與在 Java 中相同湿右。
val list = ArrayList<String>() // 非空(構(gòu)造函數(shù)結(jié)果)
list.add("Item")
val size = list.size() // 非空(原生 int)
val item = list[0] // 推斷為平臺(tái)類型(普通 Java 對象)
item.substring(1) // 允許诅妹,如果 item == null 會(huì)拋出異常
平臺(tái)類型表示法
如上所述,平臺(tái)類型不能在程序中顯式表述毅人,因此在語言中沒有相應(yīng)語法吭狡。 然而尖殃,編譯器和 IDE 有時(shí)需要(在錯(cuò)誤信息中、參數(shù)信息中等)顯示他們赵刑,所以我們用一個(gè)助記符來表示他們:
- T! 表示“T 或者 T?”分衫,
- (Mutable)Collection<T>! 表示“可以可變或不可變、可空或不可空的 T 的 Java 集合”般此,
- Array<(out) T>! 表示“可空或者不可空的 T(或 T 的子類型)的 Java 數(shù)組”
getClass():
要取得對象的 Java 類蚪战,請?jiān)陬愐蒙鲜褂?java
擴(kuò)展屬性。
val fooClass = foo::class.java
上面的代碼使用了自 Kotlin 1.1 起支持的綁定的類引用铐懊。你也可以使用 javaClass
擴(kuò)展屬性邀桑。
val fooClass = foo.javaClass
具體使用的時(shí)候就會(huì)發(fā)現(xiàn)使用的不同,例如數(shù)據(jù)類型的轉(zhuǎn)換科乎,泛型的使用壁畸,數(shù)組的使用,可變參數(shù)的傳遞茅茂,用的過程中如果發(fā)現(xiàn)不能用Java的方法捏萍,這時(shí)只需要去查詢文檔就可以了。Kotlin使用Java文檔地址
Java調(diào)用Koltin
這里只是粗略的介紹下空闲,如果要看詳細(xì)的還是請移步到官方文檔上令杈。
- Java調(diào)用Koltin的屬性時(shí),就像是Kotlin中定義了一個(gè)私有的屬性碴倾,一個(gè)get和一個(gè)set方法一樣逗噩。
- 對于與包同級(jí)的方法就像是Java的靜態(tài)方法。
- 可以使用@JvmFiled將屬性暴漏給Java
- 可以使用@JvmField跌榔,lateinit 修飾符异雁,const 修飾符暴漏出靜態(tài)字段
- 命名對象或者伴生對象的方法加入@JvmStatic,暴漏出靜態(tài)方法
- 通過調(diào)用 Class<T>.kotlin 擴(kuò)展屬性的等價(jià)形式來手動(dòng)進(jìn)行轉(zhuǎn)換
- 用 @JvmName 解決簽名沖突
- 使用 @JvmOverloads 注解生成重載
- 使用 @Throws 注解聲明受檢異常
- @JvmWildcard僧须,@JvmSuppressWildcards標(biāo)記需要和不需要通配符
總結(jié)
多多使用Kotlin開發(fā)就會(huì)體會(huì)到Kotlin與之前Java的不同纲刀,用Koltin來代替Java寫Android幾乎是沒有什么障礙的。多多實(shí)踐担平,勤加練習(xí)就能愉快的用Kotlin來開發(fā)Android了柑蛇。