Kotlin学习教程(九)

简介: Kotlin学习教程(九)

Kotlin学习教程(九)

参考往期教程:
Kotlin学习教程(一)
Kotlin学习教程(二)
Kotlin学习教程(三)
Kotlin学习教程(四)
Kotlin学习教程(五)
Kotlin学习教程(六)
Kotlin学习教程(七)
Kotlin学习教程(八)
Kotlin学习教程(九)
Kotlin学习教程(十)

Kotlin团队为Android开发提供了一套超越标准语言功能的工具:

  • Kotlin Android Extensions是一个编译器扩展,可以让您摆脱代码中的findViewById()调用,并将其替换为合成编译器生成的属性。
  • Anko是一个提供围绕Android APIDSL的一组Kotlin友好的包装器,可以用Kotlin代码替换layout .xml文件。

Anko

AnkoKotlin官方出品用于Android开发的库。

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;
Intents;
Dialogs and toasts;
Logging;
Resources and dimensions;
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使用DSL提供了很多便捷的功能,可以直接用代码去写布局,不过我还是接受不了,感觉用xml写布局把布局和逻辑区分开挺好,这里就不介绍了,想用的可以去看看。

这里就用几个简单的commons中的例子,平时想要启动另一个activity我们经常这样写:

val intent = Intent(this, SomeOtherActivity::class.java)
intent.putExtra("id", 5)
intent.setFlag(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)

这里要四行代码,太多了,anko提供了更简单的方式:

startActivity(intentFor<SomeOtherActivity>("id" to 5).singleTop())

如果不设置flag的话还可以这样写:

startActivity<SomeOtherActivity>("id" to 5)

而且anko还提供了一些常用的intent的封装功能:

  • 打电话makeCall(number) without tel
  • 发短信sendSMS(number, [text]) without sms
  • 浏览网页browse(url)
  • 分享share(text, [subject])
  • 发邮件email(email, [subject], [text])

进行toastsnakebar提示:

toast("Hi there!")
toast(R.string.message)
longToast("Wow, such duration")

snackbar(view, "Hi there!")
snackbar(view, R.string.message)
longSnackbar(view, "Wow, such duration")
snackbar(view, "Action, reaction", "Click me!") { doStuff() }

对话框:

alert("Hi, I'm Roy", "Have you tried turning it off and on again?") {
    yesButton { toast("Oh…") }
    noButton {}
}.show()

// 列表对话框
val countries = listOf("Russia", "USA", "Japan", "Australia")
selector("Where are you from?", countries, { dialogInterface, i ->
    toast("So you're living in ${countries[i]}, right?")
})

// 进度对话框
val dialog = progressDialog(message = "Please wait a bit…", title = "Fetching data")

log

class SomeActivity : Activity(), AnkoLogger {
    private fun someMethod() {
        info("London is the capital of Great Britain")
        debug(5) // .toString() method will be executed
        warn(null) // "null" will be printed
    }
}

或者:

class SomeActivity : Activity() {
    private val log = AnkoLogger<SomeActivity>(this)
    private val logWithASpecificTag = AnkoLogger("my_tag")

    private fun someMethod() {
        log.warning("Big brother is watching you!")
    }
}

dimens:

可以直接使用px2dippx2sp来进行尺寸转换。

异步操作:

doAsync {
    // Long background task
    uiThread {
        result.text = "Done"
    }
}

使用anko:

// 创建一个verticallayout并且添加edittext和button,并给button设置点击事件
verticalLayout {
    val name = editText()
    button("Say Hello") {
        onClick { toast("Hello, ${name.text}!") }
    }
}

Kotlin Android Extensions

相信每一位安卓开发人员对findViewById()这个方法再熟悉不过了,毫无疑问,潜在的bug和脏乱的代码令后续开发无从下手的。 尽管存在一系列的
开源库能够为这个问题带来解决方案,然而对于运行时依赖的库,需要为每一个View注解变量字段。

现在Kotlin安卓扩展插件能够提供与这些开源库功能相同的体验,不需要添加任何额外代码,也不影响任何运行时体验。
另一个Kotlin团队研发的可以让开发更简单的插件是Kotlin Android Extensions。当前仅仅包括了view的绑定。这个插件自动创建了很多的属性
来让我们直接访问XML中的view。这种方式不需要你在开始使用之前明确地从布局中去找到这些views

这些属性的名字就是来自对应viewid,所以我们取id的时候要十分小心,因为它们将会是我们类中非常重要的一部分。这些属性的类型也是来自
XML中的,所以我们不需要去进行额外的类型转换。

Kotlin Android Extensions的一个优点是它不需要在我们的代码中依赖其它额外的库。它仅仅由插件组层,需要时用于生成工作所需的代码,只需要依赖
Kotlin的标准库。

开发者仅需要在模块的build.gradle文件中启用Gradle安卓扩展插件即可:

apply plugin: 'kotlin-android-extensions'

我们在使用Android Sutdio 3.0创建Kotlin项目时默认已经添加了该依赖。

// 使用来自主代码集的 R.layout.activity_main
import kotlinx.android.synthetic.main.activity_main.*

class MyActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        textView.setText("Hello, world!")
        // 而不是 findViewById(R.id.textView) as TextView
    }
}

textView是对Activity的一项扩展属性,与在activity_main.xml中的声明具有同样类型。

网络请求

Kotlin提供了一些扩展函数来执行网络请求,同时也可以使用第三方库来执行.

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

如你所知,HTTP请求不被允许在主线程中执行,否则它会抛出异常。这是因为阻塞住UI线程是一个非常差的体验。Android中通用的做法是使用
AsyncTask,但是这些类是非常丑陋的,并且使用它们无任何副作用地实现功能也是非常困难的。Anko提供了非常简单的DSL来处理异步任务,
它满足大部分的需求。它提供了一个基本的async函数用于在其它线程执行代码,也可以选择通过调用uiThread的方式回到主线程。
在子线程中执行请求如下这么简单:

async() {
    Request(url).run()
    uiThread { longToast("Request performed") }
}

UIThread有一个很不错的一点就是可以依赖于调用者。如果它是被一个Activity调用的,那么如果activity.isFinishing()返回true
uiThread不会执行,这样就不会在Activity销毁的时候遇到崩溃的情况了。

解析gson

Kotlin允许我们去定义一些行为与静态对象一样的对象。尽管这些对象可以用众所周知的模式来实现,比如容易实现的单例模式。
我们需要一个类里面有一些静态的属性、常量或者函数,我们可以使用companion objecvt。这个对象被这个类的所有对象所共享,就像Java中的静态
属性或者方法。

public class ForecastRequest(val zipCode: String) {
    companion object {
        private val APP_ID = "15646a06818f61f7b8d7823ca833e1ce"
        private val URL = "http://api.openweathermap.org/data/2.5/" +
                "forecast/daily?mode=json&units=metric&cnt=7"
        private val COMPLETE_URL = "$URL&APPID=$APP_ID&q="
    }

    fun execute(): ForecastResult {
        val forecastJsonStr = URL(COMPLETE_URL + zipCode).readText()
        return Gson().fromJson(forecastJsonStr, ForecastResult::class.java)
    }
}

创建Application

class App : Application() {
    companion object {
        private var instance: Application? = null
        fun instance() = instance!!
    }
    override fun onCreate() {
        super.onCreate()
        instance = this
    }
}
  • with()
inline fun <T> with(t: T, body: T.() -> Unit) { t.body() }

参考


相关文章
|
1天前
|
Java 网络架构 Kotlin
kotlin+springboot入门级别教程,教你如何用kotlin和springboot搭建http
本文是一个入门级教程,介绍了如何使用Kotlin和Spring Boot搭建HTTP服务,并强调了Kotlin的空安全性特性。
14 7
kotlin+springboot入门级别教程,教你如何用kotlin和springboot搭建http
|
1天前
|
前端开发 Java API
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
本文是Vert.x学习系列的第五部分,讨论了回调函数的限制、Future和Promise在异步操作中的应用、响应式扩展以及Kotlin协程,并通过示例代码展示了如何在Vert.x中使用这些异步编程模式。
11 5
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
|
1天前
|
Java Maven Kotlin
vertx的学习总结7之用kotlin 与vertx搞一个简单的http
本文介绍了如何使用Kotlin和Vert.x创建一个简单的HTTP服务器,包括设置路由、处理GET和POST请求,以及如何使用HTML表单发送数据。
9 2
vertx的学习总结7之用kotlin 与vertx搞一个简单的http
|
1天前
|
存储 Java 编译器
Kotlin学习教程(八)
Kotlin学习教程(八)
|
1天前
|
存储 Java API
Kotlin学习教程(六)
Kotlin学习教程(六)
14 2
|
1天前
|
Java Kotlin
Kotlin学习教程(十)
Kotlin学习教程(十)
|
1天前
|
Java Kotlin
Kotlin学习教程(七)
Kotlin学习教程(七)
11 0
|
JavaScript Java Android开发
Kotlin学习探索-前言
一些故事: 说到Kotlin,首先不提不提到耳熟能详的Java。我们知道Java这门强类型语言的应用范围实在是太广了。JavaSe、JavaMe、JavaEE开发、Android开发、大数据开发(如比较出名的Hadoop,Hadoop是用Java语言编写)、Java也可以用做游戏开发,Java经典游戏代表作有:《我的世界》等,连跟Java没什么关系的JavaScript这一脚本语言,在命名之初都要加上Java的前缀,以此来提高较好的口碑(因为有Java的字样,会让人误以为跟Java有什么关系)。
1733 0
|
28天前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
53 1
|
2月前
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
42 4