使用Kotlin進行Android開發

JaysonBcf 8年前發布 | 26K 次閱讀 Kotlin Android

What is Kotlin

Kotlin,原意是在俄羅斯的一個小島,JetBrain在2011年推出了以這個來命名的一個運行在JVM上的語言, 看上去有點類似C#和Scala的結合,并且同為靜態類型,作為一門JVM上的語言,可以輕松兼容Java,并且整個語言設計的非常輕量。目前的版本為0.12.200,尚未發布正式版。

Kotlin的下載和配置在其官網上有,在這里就不再贅述了,值得一提的是,作為JetBrains家出品的語言,自家的IDEA當然全力支持!

基本語法介紹

Kotlin的語法非常簡潔,熟悉Java或者Scala的人都可以快速上手:

函數聲明:

fun foo(va: Int): Int {
    return 1
}

也可以單行聲明:

fun foo(va: Int): Int = 1

lambda當然也是支持的:

var c = {foo: Int -> println(foo)}

Kotlin中的函數是一等對象,自然支持高階函數:

var c = {foo: Int -> println(foo)}
fun fooTest(func: (Int)->()) = println("I'm Groot")    
fooTest(c)

 

類與接口

類可以這樣進行聲明:

class Bar(var b: Int): Foo() {
    var c = 1
    init {
        println("class initializer")
    }

constructor(): this(1) {
    println("secondary constructor")
}

}</code></pre>

Bar類在這里繼承了Foo類,Bar類有兩個構造函數,直接在Bar類頭的是primary constructor,另外一個構造函數使用constructor關鍵字定義,注意必須要先調用primary constructor,另外,init標明的是class initializer,每個構造函數都會首先調用class initializer里面的代碼,再調用構造函數

Inner class:

class Outer {
    class Inner {      
    }
}

Kotlin同樣支持嵌套的內部類,不過和Java不一樣的是,Kotlin的內部類不會默認包含一個指向外部類對象的引用,也就是說,Kotlin中所有的內部類默認就是靜態的,這樣可以減少很多內存泄露的問題。另外,如果需要在內部類中引用外部類對象,可以在Inner類的聲明前加上inner關鍵字,然后在Inner類中使用標記的thisthis@Outer來指向外部類對象

Singleton:

object Single {
    var c = 1

fun foo() = println("foo")

}</code></pre>

Kotlin中使用object關鍵字聲明一個singleton對象,后面這里的方法就可以直接使用Single.foo()來調用了

Interface:

interface Interface {
    fun foo() {
        println(1)
    }
    fun bar()
}

Kotlin中的interface,跟其他語言的trait非常像,而且也可以帶有默認的實現方法,并且不允許通過屬性來維護狀態。事實上,在上個版本中,interface的原來名稱是trait,而在M12現在這個版本中又改成了interface而已

 

Null safe and Smart type cast

Null safe:

在Kotlin中,嚴格區分了nullable和非nullable對象,甚至在編譯期解決了不少潛在的空指針問題:

我們先來看下普通的變量聲明

var c: String = "12123"

這里聲明了一個String對象,其值為"12123",我們可以正常的使用這個對象的成員方法:c.length()

但是,如果在初始化的時候,變量c為空的話,這樣聲明就是錯誤的,會編譯不過:

var c: String = null

正確的聲明應該是這樣:

var c: String? = null

這里在String后面加多了一個問號,表明這里是一個Nullable的對象,說明這個變量在使用的過程中可能為空,而且,在調用這個變量的成員的時候,必須要使用這種語法:c?.length(),在調用的時候添加了一個問號,表明,如果c為空的時候,length()這個方法就不會調用。coffe-script也有類似的,這種語法糖減少了很多平時用到的Null-checked,簡化了代碼,而且從編譯器開始介入null-checked,大大減少了潛在的NullPointerException,而事實上,null的確也是一個billion dollar mistake

常年進行如此的調用語法常常會很惱人,因此在你進行顯式的Null-checked的時候,Kotlin的編譯器會認為后續的調用已經無需進行Null-checked,可以直接調用了:

if (c != null) {
    c.length()
}

Smart type cast

在Kotlin中,進行強制類型轉換可以使用as關鍵字,但有可能會拋出異常,因此,Kotlin引入了smart type cast:

if (c is String) {
    c.length()
}

在上面的例子中,如果c是一個String對象,則在if塊中,可以直接使用String的方法,編譯器會智能的幫你識別出c在if-blcok里面是一個String對象

Pattern Matching

Kotlin在一定程度上支持了一些FP的特性,包括強大的Pattern Matching,在Kotlin中可以使用when關鍵字:

var x = 3
when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    in 1..10 -> print("x is in the range")
    !in 10..20 -> print("x is outside the range")
    is Int -> println("is int")
    else -> { // Note the block
      print("x is neither 1 nor 2")
    }
}

Function Extension

在Java中我們經常需要給系統的類添加一些實用的方法,但苦于不能直接擴展,于是就有了各種的xxxUtils類,導致代碼非常惡心,但是在Kotlin中,我們可以直接擴展庫里面類的方法,通過function extension:

fun String.fucker() {
    println("a fucker")
}

上面給String類添加了一個fucker方法,我們可以直接使用:

"123123".fucker()

這大大的減少了我們寫xxxUtils類的必要性

配置使用Kotlin進行Android開發

使用Kotlin開發Android app的配置非常簡單,按照官方給出的配置即可,直接在Gradle的配置文件build.gradle中添加一個依賴:

compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

然后添加Kotlin插件的使用:

apply plugin: 'kotlin-android'

進行一次Gradle Sync之后,就可以直接在項目使用Kotlin編寫代碼了,另外,如果安裝了Intellij的Kotlin插件,可以選擇 Tools->Kotlin->Configure Kotlin in Project,就可以自動進行上述的配置,一步到位

我寫了一個簡單的Demo app放到了Github上,有興趣可以看下使用Kotlin開發android app具體是怎樣的:Demo地址

對于dex方法數目的影響

dex有個65535方法數的限制,這對Android開發造成了很大的影響,在使用Kotlin進行android app開發的時候,需要將Kotlin的標準庫打包進入apk中,這意味著如果標準庫過大,對分包會造成很大的限制(因為這必須得打包在主dex中),所幸的是,Kotlin的哲學是“Java中有的,就盡量復用,不再自行創造一套”,使得整個Kotlin的標準庫非常小,我們可以簡單將Kotlin的標準庫和其他比較常用庫進行一下對比:

包名 android-support-v13.jar android-support-v4.jar android-support-v7-appcompat.jar guava-18.0.jar scala-library-2.12.0-M1.jar kotlin-stdlib-0.12.213.jar
方法數 8219 8118 4624 14833 51248 7228


可以看出來Kotlin的標準庫相當小,只有7000多個方法,比support-v13和support-v4還小,這體現了Kotlin的設計哲學之一:"100% interoperable with Java",基本上Java已經有的,Kotlin會盡量復用。而對比來看,同樣是JVM上的語言,我們也可以選擇使用Scala來進行Android開發,但Scala標準庫有5萬多個方法,全部打包進主dex中,很容易就導致app爆主dex了。所以綜合來看,輕量形的Kotlin還是相當適合進行Android開發的。

Project Anko

Anko 是JetBrains推出的一個簡化Android開發的庫,同樣由Kotlin來編寫,主要的革命在于,聲明UI的方式,完全拋棄了xml的使用,使用Anko,聲明UI是這樣做的:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val customStyle = { v: Any ->
        when (v) {
            is Button -> v.textSize = 26f
            is EditText -> v.textSize = 24f
        }
    }

verticalLayout {

    padding = dip(34)
    imageView(android.R.drawable.ic_menu_manage).layoutParams {
        margin = dip(16)
        gravity = Gravity.CENTER
    }

     val name = editText {
         hintResource = R.string.name
    }
    val password = editText {
        hintResource = R.string.password
        inputType = TYPE_CLASS_TEXT or TYPE_TEXT_VARIATION_PASSWORD
    }

    button("Log in") {
        onClick {
            tryLogin(name.text, password.text)
        }
    }
}.style(customStyle)

}</code></pre>

你沒看錯,的確是在Activity類的onCreate方法中直接聲明UI的布局。

Anko看起來像是使用了一種類似DSL的方式聲明了界面的UI,這里主要是使用了Kotlin的其中兩個特性:

  • Function Extension,Anko擴展了Activity類,提供了額外的方法和屬性
  • Kotlin在調用函數的時候,如果最后一個參數為函數的話,則可以直接使用Lambda,并省略括號

因此這里聲明布局的方式,其實全是Kotlin的原生代碼,鵝妹子嚶!這樣做有顯然的好處:

  • 由于實際上全是由代碼來布局,省去了解析xml的時間
  • xml本身有許多缺點,例如不可重用,非類型安全等,使用代碼布局的話,我們可以很容易的就解決這個問題了

 

來自:http://blog.csdn.net/chaoyu168/article/details/52047687

 

 本文由用戶 JaysonBcf 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!