標籤:dap 成本 思考 對象 tracking setters hello tostring 資料
本文來源於我在InfoQ中文站翻譯的文章,原文地址是:http://www.infoq.com/cn/news/2016/01/kotlin-android
Android開發人員在語言限制方面面臨著一個困境。
眾所周知,眼下的Android開發僅僅支援Java 6(語言本身從Java 7開始進行了一些改進),因此我們每天僅僅能使用一種古老的語言來進行開發,這極大地減少了我們的生產力,同一時候也迫使我們不得不編寫大量的樣板與脆弱的代碼。然而這種代碼是難以閱讀和維護的。
幸運的是,Android程式是執行在Java虛擬機器之上的,因此從技術上來說,能夠執行在JVM之上的一切都可用於開發Android應用。如今已經有許多能夠產生JVM能夠執行的位元組碼的語言,當中一些語言開始嶄露頭角並逐步流行起來,Kotlin就是當中的佼佼者。
何為Kotlin?
Kotlin是一門執行在JVM之上的語言。它由Jetbrains建立。而Jetbrains則是諸多強大的工具(如知名的Java IDE IntelliJ IDEA)背後的公司。
Kotlin是一門很easy的語言,其主要目標之中的一個就是提供強大語言的同一時候又保持簡單且精簡的文法。其主要特性例如以下所看到的:
眼下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?
過程很easy,僅僅需依照以下的步驟來就可以:
- 從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 = titletextView.text = titlecontactsList.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
Android開發人員應該知道的Kotlin