Android開發者在語言限制方面面臨著一個困境。眾所周知,目前的Android開發只支持Java 6(語言本身從Java 7開始進行了一些改進),因此我們每天只能使用一種古老的語言來進行開發,這極大地降低了我們的生產力,同時也迫使我們不得不編寫大量的樣板與脆弱的代碼,然而這樣的代碼是難以閱讀和維護的。幸運的是,Android程序是運行在Java虛擬機之上的,因此從技術上來說,可以運行在JVM之上的一切都可用于開發Android應用。現在已經有很多可以生成JVM能夠執行的字節碼的語言,其中一些語言開始嶄露頭角并逐步流行起來,Kotlin就是其中的佼佼者。
何為Kotlin?
Kotlin是一門運行在JVM之上的語言。它由Jetbrains創建,而Jetbrains則是諸多強大的工具(如知名的Java IDE IntelliJ IDEA)背后的公司。Kotlin是一門非常簡單的語言,其主要目標之一就是提供強大語言的同時又保持簡單且精簡的語法。其主要特性如下所示:
輕量級:這一點對于Android來說非常重要。項目所需要的庫應該盡可能的小。Android對于方法數量有嚴格的限制,Kotlin只額外增加了大約6000個方法。
互操作:Kotlin可與Java語言無縫通信。這意味著我們可以在Kotlin代碼中使用任何已有的Java庫;因此,即便這門語言還很年輕,但卻已經可以使用成百上千的庫了。除此之外,Kotlin代碼還可以為Java代碼所用,這意味著我們可以使用這兩種語言來構建軟件。你可以使用Kotlin開發新特性,同時使用Java實現代碼基的其他部分。
強類型:我們很少需要在代碼中指定類型,因為編譯器可以在絕大多數情況下推斷出變量或是函數返回值的類型。這樣就能獲得兩個好處:簡潔與安全。
Null安全:Java最大的一個問題就是null。如果沒有對變量或是參數進行null判斷,那么程序當中就有可能拋出大量的NullPointerException,然而在編碼時這些又是難以檢測到的。Kotlin使用了顯式的null,這會強制我們在必要時進行null檢查。
目前Kotlin的版本是1.0.0 Beta 3,不過正式版很快就會發布。它完全可以用在生產當中,現在就已經有很多公司成功應用上了Kotlin。
為何說Kotlin非常適合于Android?
基本上,這是因為Kotlin的所有特性都非常適合于Android生態圈。Kotlin的庫非常小,我們在開發過程中不會引入額外的成本。其大小相當于support-v4庫,我們在很多項目中所使用的庫都比Kotlin大。除此之外,Android Studio(官方的Android IDE)是基于IntelliJ構建的。這意味著我們的IDE對該語言提供了非常棒的支持。我們可以很快就配置好項目,并且使用熟悉的IDE進行開發。我們可以繼續使用Gradle以及IDE所提供的各種運行與調試特性。這與使用Java開發應用別無二致。歸功于互操作性,我們可以在Kotlin代碼中使用Android SDK而不會遇到任何問題。實際上,部分SDK使用起來會變得更加簡單,這是因為互操作性是非常智能的,比如說它可以將getters與setters映射到Kotlin屬性上,我們也可以以閉包的形式編寫監聽器。
如何在Android開發中使用Kotlin?
過程非常簡單,只需按照下面的步驟來即可:
從IDE plugins中下載Kotlin插件
在模塊中創建Kotlin類
使用“Configure Kotlin in Project…”
開始編碼
Kotlin的一些特性
Kotlin擁有大量非常打動人心的特性,這里無法一一進行介紹,不過我們來看一下其中最為重要的一些。
Null安全
如前所述,Kotlin是null安全的。如果一個類型可能為null,那么我們就需要在類型后面加上一個?。這樣,每次在使用該類型的變量時,我們都需要進行null檢查。比如說,如下代碼將無法編譯通過:
var artist: Artist? = null? artist.print()
第2行會顯示一個錯誤,因為沒有對變量進行null檢查。我們可以這樣做:
if (artist != null) { ? artist.print()? }
這展示了Kotlin另一個出色的特性:智能類型轉換。如果檢查了變量的類型,那就無需在檢查作用域中對其進行類型轉換。這樣,我們現在就可以在if中將artist作為Artist類型的變量了。這對于其他檢查也是適用的。還有一種更簡單的方式來檢查null,即在調用對象的函數前使用?。甚至還可以通過Elvis運算符?提供另外一種做法:
val name = artist?.name ?: ""
數據類
在Java中,如果想要創建數據類或是POJO類(只保存了一些狀態的類),我們需要創建一個擁有大量字段、getters與setters的類,也許還要提供toString與equals方法:
public class Artist { private long id; private String name; private String url; private String mbid; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getMbid() { return mbid; } public void setMbid(String mbid) { this.mbid = mbid; } @Override public String toString() { return "Artist{" + "id=" + id + ", name='" + name + ''' + ", url='" + url + ''' + ", mbid='" + mbid + ''' + '}'; } }
在Kotlin中,上述代碼可以寫成下面這樣:
data class Artist (? var id: Long, var name: String, var url: String, var mbid: String)
Kotlin使用屬性而非字段。基本上,屬性就是字段加上其getter與setter。
互操作
Kotlin提供了一些非常棒的互操作特性,這對于Android開發幫助非常大。其中之一就是擁有單個方法的接口與lambda表達式之間的映射。這樣,下面這個單擊監聽器:
view.setOnClickListener(object : View.OnClickListener { override fun onClick(v: View) { toast("Click")? } ?})
可以寫成這樣:
view.setOnClickListener { toast("Click") }
此外,getters與setters都會自動映射到屬性上。這并不會造成性能上的損失,因為字節碼實際上只是調用原來的getters與setters。如下代碼所示:
supportActionBar.title = title textView.text = title contactsList.adapter = ContactsAdapter()
Lambda表達式
Lambda表達式會在極大程度上精簡代碼,不過重要的是借助于Lambda表達式,我們可以做到之前無法實現或是實現起來非常麻煩的事情。借助于Lambda表達式,我們可以以一種更加函數式的方式來思考問題。Lambda表達式其實就是一種指定類型,并且該類型定義了一個函數的方式。比如說,我們可以像下面這樣定義一個變量:
val listener: (View) -> Boolean
該變量可以聲明一個函數,它接收一個view并返回這個函數。我們需要通過閉包的方式來定義函數的行為:
val listener = { view: View -> view is TextView }
上面這個函數會接收一個View,如果該view是TextView的實例,那么它就會返回true。由于編譯器可以推斷出類型,因此我們無需指定。還可以更加明確一些:
val listener: (View) -> Boolean = { view -> view is TextView }
借助于Lambda表達式,我們可以拋棄回調接口的使用。只需設置希望后面會被調用的函數即可:
fun asyncOperation(value: Int, callback: (Boolean) -> Unit) { ... callback(true)? } asyncOperation(5) { result -> println("result: $result") }
還有一種更加簡潔的方式,如果函數只接收一個參數,那就可以使用保留字it:
asyncOperation(5) { println("result: $it") }
Anko
Anko是Kotlin團隊開發的一個庫,旨在簡化Android開發。其主要目標在于提供一個DSL,使用Kotlin代碼來聲明視圖:
verticalLayout { val name = editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } }
它還提供了其他一些很有用的特性。比如說,導航到其他Activity:
startActivity("id" to res.id, "name" to res.name)
總結
如你所見,Kotlin在很多方面都簡化了Android的開發工作。它會提升你的生產力,并且可以通過非常不同且更加簡單的方式來解決一些常見的問題。
?
評論
查看更多