kotlin学习(三)

Anko是什么?

Anko是JetBrains开发的一个强大的库。它主要的目的是用来替代以前XML的方式来使用代码生成UI布局。这是一个很有趣的特性,我推荐你可以尝试下,但是我在这个项目中暂时不使用它。对于我(可能是由于多年的UI绘制经验)来说使用XML更容易一些,但是你会喜欢那种方式的。

然而,这个不是我们能在这个库中得到的唯一一个功能。Anko包含了很多的非常有帮助的函数和属性来避免让你写很多的模版代码。我们将会通过本书见到很多例子,但是你应该快速地认识到这个库帮你解决了什么样的问题。

尽管Anko是非常有帮助的,但是我建议你要理解这个背后到底做了什么。你可以在任何时候使用ctrl + 点击(Windows)或者cmd + 点击(Mac)的方式跳转到Anko的源代码。Anko的实现方式对学习大部分的Kotlin语言都是非常有帮助的。

开始使用Anko

在之前,让我们来使用Anko来简化一些代码。就像你将看到的,任何时候你使用了Anko库中的某些东西,它们都会以属性名、方法等方式被导入。这是因为Anko使用了扩展函数在Android框架中增加了一些新的功能。我们将会在以后看到扩展函数是什么,怎么去编写它。

MainActivity:onCreate,一个Anko扩展函数可以被用来简化获取一个RecyclerView:

val forecastList: RecyclerView = find(R.id.forecast_list)

我们现在还不能使用库中更多的东西,但是Anko能帮助我们简化代码,比如,实例化Intent,Activity之间的跳转,Fragment的创建,数据库的访问,Alert的创建……我们将会在实现这个App的过程中学习到很多有趣的例子。

扩展函数

扩展函数数是指在一个类上增加一种新的行为,甚至我们没有这个类代码的访问权限。这是一个在缺少有用函数的类上扩展的方法。在Java中,通常会实现很多带有static方法的工具类。Kotlin中扩展函数的一个优势是我们不需要在调用方法的时候把整个对象当作参数传入。扩展函数表现得就像是属于这个类的一样,而且我们可以使用this关键字和调用所有public方法。

举个例子,我们可以创建一个toast函数,这个函数不需要传入任何context,它可以被任何Context或者它的子类调用,比如Activity或者Service:

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

这个方法可以在Activity内部直接调用:

toast("Hello world!")
toast("Hello world!", Toast.LENGTH_LONG)

当然,Anko已经包括了自己的toast扩展函数,跟上面这个很相似。Anko提供了一些针对CharSequenceresource的函数,还有两个不同的toast和longToast方法:

toast("Hello world!")
longToast(R.id.hello_world)

扩展函数也可以是一个属性。所以我们可以通过相似的方法来扩展属性。下面的例子展示了使用他自己的getter/setter生成一个属性的方式。Kotlin由于互操作性的特性已经提供了这个属性,但理解扩展属性背后的思想是一个很不错的练习:

public var TextView.text: CharSequence
    get() = getText()
    set(v) = setText(v)

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

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

执行一个请求

对于感受我们要实现的想法而言,我们目前的文本是很好开始,但是现在是时候去请求一些显示在RecyclerView上的真正的数据了。我们将会使用OpenWeatherMap API来获取数据,还有一些普通类来现实这个请求。多亏Kotlin非常强大的互操作性,你可以使用任何你想使用的库,比如用Retrofit来执行服务器请求。当只是执行一个简单的API请求,我们可以不使用任何第三方库来简单地实现。

而且,如你所见,Kotlin提供了一些扩展函数来让请求变得更简单。首先,我们要创建一个新的Request类:

public class Request(val url: String) {
    public fun run() {
        val forecastJsonStr = URL(url).readText()
        Log.d(javaClass.simpleName, forecastJsonStr)
    }
}

我们的请求很简单地接收一个url,然后读取结果并在logcat上打印json。实现非常简单,因为我们使用readText,这是Kotlin标准库中的扩展函数。这个方法不推荐结果很大的响应,但是在我们这个例子中已经足够好了。

如果你用这些代码去比较Java,你会发现我们仅使用标准库就节省了大量的代码。比如HttpURLConnectionBufferedReader和需要达到相同效果所必要的迭代结果,管理连接状态、reader等部分的代码。很明显,这些就是场景背后函数所作的事情,但是我们却不用关心。

为了可以执行请求,App必须要有Internet权限。所以需要在AndroidManifest.xml中添加::

<uses-permission android:name="android.permission.INTERNET" />


你可能感兴趣的:(kotlin,android)