zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

[Android Studio] Kotlin - Drastically reduce the amount of boilerplate code

AndroidKotlinStudiocode The of reduce
2023-09-27 14:23:25 时间

本篇仅仅是初步感受Kotlin.

当然还有不得不说的Anko

"特性实在太多了,导致工程性反而受到了削弱。但是 Anko 真的是 Kotlin 上的 killer app"

anko-DSL-preview,UI预览工具 

使用Kotlin&Anko, 扔掉XML开发Android应用

 

参考:

Office: https://kotlinlang.org/

Android with Kotlin: https://developer.android.com/kotlin/get-started.html

Ref: Kotlin vs Java The Whole StoryKotlin与Java之争

 

阅读急先锋:

先一般而言,先把中文版的资料迅速过一遍,毕竟是母语。

https://wangjiegulu.gitbooks.io/kotlin-for-android-developers-zh/

 

如果你觉得Java 7是一个过期的语言,并决定找一个更现代的语言代替。恭喜你!就如你知道的,虽然Java 8已经发布了,它包含了很多我们期待的像现代语言中那样的改善,但是我们Android开发者还是被迫在使用Java 7.这是因为法律的问题。

但是就算没有这个限制,并且新的Android设备从今天开始使用新的能理解Java8的VM,在当前的设备过期、几乎没有人使用它们之前我们也不能使用Java 8,所以恐怕我们不会很快等到这一天的到来。

但是并不是没有补救的方法。多亏使用了JVM,我们可以使用任何语言去编写Android应用,只要它能够编译成JVM能够认识的字节码就可以了。

正如你所想,有很多选择,比如Groovy,Scala,Clojure,当然还有Kotlin。通过实践,只有其中一些能够被考虑来作为替代品。

上述的每一种语言都有它的利弊,如果你还没有真正确定你该使用那种语言,我建议你可以去尝试一下它们。
为什么使用

 

相比Java 7的优势到底是什么呢?

  • 它更加易表现:这是它最重要的优点之一。你可以编写少得多的代码。
  • 它更加安全:Kotlin是空安全的,也就是说在我们编译时期就处理了各种null的情况,避免了执行时异常。如果一个对象可以是null,则我们需要明确地指定它,然后在使用它之前检查它是否是null。你可以节约很多调试空指针异常的时间,解决掉null引发的bug。
  • 它是函数式的:Kotlin是基于面向对象的语言。但是就如其他很多现代的语言那样,它使用了很多函数式编程的概念,比如,使用lambda表达式来更方便地解决问题。其中一个很棒的特性就是Collections的处理方式。
  • 它可以扩展函数:这意味着我们可以扩展类的更多的特性,甚至我们没有权限去访问这个类中的代码。
  • 它是高度互操作性的:你可以继续使用所有的你用Java写的代码和库,因为两个语言之间的互操作性是完美的。甚至可以在一个项目中使用Kotlin和Java两种语言混合编程。

 

关于优势,给些大概例子如下: 

数据类的访问:

在Java中,如果我们要典型的数据类:

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;
    }

...
}

使用Kotlin,我们只需要通过数据类:

data class Artist(
    var id: Long,
    var name: String,
    var url: String,
    var mbid: String )

自动生成所有属性和它们的访问器,以及一些有用的方法,比如,toString()

 

空安全:

// 这里不能通过编译. Artist 不能是null
var notNullArtist: Artist = null

// Artist 可以是 null
var artist: Artist? = null

// 无法编译, artist可能是null,我们需要进行处理
artist.print()

// 只要在artist != null时才会打印
artist?.print()

// 智能转换. 如果我们在之前进行了空检查,则不需要使用安全调用操作符调用
if (artist != null) {
  artist.print()
}

// 只有在确保artist不是null的情况下才能这么调用,否则它会抛出异常
artist!!.print()

// 使用Elvis操作符来给定一个在是null的情况下的替代值
val name = artist?.name ?: "empty"

 

扩展方法:

fun Fragment.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) { 
    Toast.makeText(getActivity(), message, duration).show()
}

总之,就是代码书写更加简洁

fragment.toast("Hello world!")

 

函数式支持(Lambdas):

例如点击触发事件若强制遵循面向对象,有些麻烦,所以函数式也有一定的好处。

 

 

Andorid Studio with Kotlin

Ref: Getting started with Android and Kotlin

Ref: Create a new project with Kotlin

The Kotlin plugin is bundled with Android Studio starting from version 3.0.

If you use an earlier version,

you'll need to install the Kotlin plugin. Go to File | Settings | Plugins | Install JetBrains plugin… and then search for and install Kotlin. If you are looking at the "Welcome to Android Studio" screen, choose Configure | Plugins | Install JetBrains plugin… You'll need to restart the IDE after this completes.
Solution

所以,安装Android Studio 3.0.1就好了。

 

终归就是神奇的命令:

Code > Convert Java File to Kotlin File.

 

 以上就是基本内容。

 

 


 

 

Start from here: https://wangjiegulu.gitbooks.io/kotlin-for-android-developers-zh/lei_he_han_shu.html

 

Class 

  • 类的构造方法:
class Person(name: String, surname: String) {
    init{
        ...
    }
}

 

  • 只能继承声明open或者abstract的类:
open class Animal(name: String)
class Person(name: String, surname: String) : Animal(name)

当我们只有单个构造器时,我们需要在从父类继承下来的构造器中指定需要的参数。

这是用来替换Java中的super调用的。 

 

Function

  • 定义:为了protest,有点丑陋的函数定义。
fun add(x: Int, y: Int) : Int {
    return x + y
}

有点宏的效果

fun add(x: Int,y: Int) : Int = x + y

 

  • Default paramenters
fun toast(message: String, length: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(this, message, length).show()
}

 

Variables

  • 在Kotlin中,一切都是对象。没有像Java中那样的原始基本类型。
val i: Int=7
val d: Double = i.toDouble()

例子:

val c: Char='c'
val i: Int = c.toInt()
val bitwiseOr  = FLAG1 or FLAG2
val bitwiseAnd = FLAG1 and FLAG2
// 也可以自动识别
val i = 12 // An Int val iHex = 0x0f // 一个十六进制的Int类型 val l = 3L // A Long val d = 3.5 // A Double val f = 3.5F // A Float
// 字符串处理
val s = "Example" val c = s[2] // 这是一个字符'a' // 迭代String val s = "Example" for(c in s){ print(c) }

 

变量可以很简单地定义成可变(var)不可变(val的变量。

不可变在Kotlin(和其它很多现代语言)中是一个很重要的概念。

 

数据类

  • 不再需要繁琐的getxxx(), setxxx()。
// 默认使用getter和setter

public
class Person { var name: String = "" } ... val person = Person() person.name = "name" val name = person.name

// 自定义的getter和setter
public classs Person {
    var name: String = ""
        get() = field.toUpperCase()
        set(value){
            field = "Name: $value"
        }
}

 

如果需要在getter和setter中访问这个属性自身的值,它需要创建一个backing field。可以使用field这个预留字段来访问,它会被编译器找到正在使用的并自动创建。

需要注意的是,如果我们直接调用了属性,那我们会使用setter和getter而不是直接访问这个属性。backing field只能在属性访问器内访问

就如在前面章节提到的,当操作Java代码的时候,Kotlin将允许使用属性的语法去访问在Java文件中定义的getter/setter方法。编译器会直接链接到它原始的getter/setter方法。所以当我们直接访问属性的时候不会有性能开销。

 

  • equals(): 它可以比较两个对象的属性来确保他们是相同的。
  • hashCode(): 我们可以得到一个hash值,也是从属性中计算出来的。
  • copy(): 你可以拷贝一个对象,可以根据你的需要去修改里面的属性。
val f1 = Forecast(Date(), 27.5f, "Shiny day")
val f2 = f1.copy(temperature = 30f)
  •  映射到变量中
val f1 = Forecast(Date(), 27.5f, "Shiny day")
val (date, temperature, details) = f1
val date = f1.component1()
val temperature = f1.component2()
val details = f1.component3()
等价

 

该特性的经典运用:

for ((key, value) in map) {
    Log.d("map", "key:$key, value:$value")
}

  

扩展函数

在一个类上增加一种新的行为,甚至我们没有这个类代码的访问权限。这是一个在缺少有用函数的类上扩展的方法。

在Java中,通常会实现很多带有static方法的工具类。

Kotlin中扩展函数的一个优势是我们不需要在调用方法的时候把整个对象当作参数传入。扩展函数表现得就像是属于这个类的一样,而且我们可以使用this关键字和调用所有public方法。

 

扩展函数并不是真正地修改了原来的类,它是以静态导入的方式来实现的。扩展函数可以被声明在任何文件中,因此有个通用的实践是把一系列有关的函数放在一个新建的文件里。

这是Anko功能背后的魔法。现在通过以上,你也可以自己创建你的魔法。

详见:[Android Kotlin] lec03, Anko

 

 

 


 

 

From: github传送门

Anko is a Kotlin library which makes Android application development faster and easier. It makes your code clean and easy to read, and lets you forget about rough edges of the Android SDK for Java.

Anko consists of several parts:

  • Anko Commons: a lightweight library full of helpers for intents, dialogs, logging and so on;
  • Anko Layouts: a fast and type-safe way to write dynamic Android layouts;
  • Anko SQLite: a query DSL and parser collection for Android SQLite;
  • Anko Coroutines: utilities based on the kotlinx.coroutines library.

 

用了 Anko 基本就可以告别那些什么 Android 不得不知的代码收集贴了。

 

  • anko-commons库,一些通用功能,集成方式:
dependencies {
//anko_version脚本配置,下同,本文中,该值为0.10.0
    compile "org.jetbrains.anko:anko-commons:$anko_version"
}

 

  • anko-layout库,牛逼的dsl(领域特定语言)功能,布局的另一种代码方式,相对比较简洁,xml的简易替代。集成方式:
dependencies {
    // Anko Layouts
    compile "org.jetbrains.anko:anko-sdk25:$anko_version" // sdk15, sdk19, sdk21, sdk23 are also available
    compile "org.jetbrains.anko:anko-appcompat-v7:$anko_version"

    // 主要为兼容一些控件事件的协程,不过协程coroutines目前还不是kotlin的正式内容
    compile "org.jetbrains.anko:anko-sdk25-coroutines:$anko_version"
    compile "org.jetbrains.anko:anko-appcompat-v7-coroutines:$anko_version"
}

 

  • anko-sqlite库,见名知义,简化sqlite使用的库,集成方式:
dependencies {
  compile "org.jetbrains.anko:anko-sqlite:$anko_version"
}

 

  • anko-coroutines库,集成方式:
dependencies {
    compile "org.jetbrains.anko:anko-coroutines:$anko_version"
}

 

Continue...