Kotlin 实践

500 查看

Kotlin,其语法来自: Swift, C#, Go?

优点:

  • 非常简洁的语法,代码量锐减,老板要扣薪水了!
  • 与Java代码交互非常容易和简单
  • 更好的泛型
  • 安全的null运算, 跟Swift的一样
  • 更好的Lambda支持
  • 方法(函数)为一级公民
  • 扩展方法
  • inline
  • 还有一系列的语法糖: range, data class 等

以下是我在项目中的一些实践:

1, 对String进行扩展方法后,网络请求变成了这样

// 异步搜索App
fun searchApps(callback: (AppInfo?) -> Unit) {
    var url = "http://www.xxxx.com/app/"
    url.addHeader("user-agent", "kotlin")
            .addQueryString("q", "GooglePlay")
            .httpGet {
                resp ->
                var app = resp.content?.toJson(javaClass<AppInfo>())
                callback(app)
            }
}

异步请求应用信息,并转换为AppInfo对象
网络请求封装了AsyncHttpClient/async-http-client · GitHub, Json转换封装了 alibaba/fastjson · GitHub (为了简约起见,忽略了其他逻辑,下同)

2, 为 Activity 和 Fragment 增加了异步操作扩展

class MainActivity : Activity() {
    fun asyncSample() {
        async({
            // 这里的代码执行在 *线程池* 中
            // 返回值自动传入下一个参数
            verySlowMethod()
         }) {

            // 读取上一个参数的值
            // 并且在 *主线程* toast出来
            str->
            str.toast(this)
        }
    }
}

fun verySlowMethod(): String {
    Thread.sleep(2000)
    return "kotlin"
}

// async 函数定义
fun async<T>(background: ()-> T, foreground:(T) -> Unit) {
    checkPool()
    pool?.submit() {
        val t:T = background()
        runOnUIThread {
            foreground(t)
        }
    }
}

// 为Activity增加扩展
inline fun Context.async<T>(noinline b:() -> T, @noinline f:(T) -> Unit) = ThreadExt.async(b, f)

{% endhighlight %}

也可以这样

{% highlight kotlin %}
fun requestApps() {
    showProgressBar()
    AppApi.getHotApps {
        hotApps ->
        ui {
            // 该块内的代码将执行在主线程
            hideProgressBar()

            if (hotApps.size() == 0) {
                // no data, retry
                showRetryButton {
                    v ->
                    requestApps()
                }
            } else {
                adapter?.apps = hotApps
            }
        }
    }
}

代码解释,功能是请求应用列表,请求时显示进度条,失败显示重试按钮,点击重试按钮,重新请求数据,如此反复,请求到数据到,将数据交给RecyclerView adapter, 并填充。

其中 getHotApps为异步函数,其参数为网络请求完毕后的callback。

ui为Fragment或者Activity的扩展方法,其块内的代码执行在主线程。

(Kotlin的语法糖,如果最后一个参数为Lambda表达式,那么可以不写在参数列表中, 如果Lambda表达式没有参数,可以不写 -> )

3,对属性的支持,类似C#,麻麻再也不担心我写get set函数啦。

inner class AppAdapter : RecyclerView.Adapter<AppViewHolder>() {

      var apps: ArrayList<AppInfo>? = null
          set (value) {
              $apps = value
              notifyDataSetChanged()
          }

      // 省略其他代码
}

这里使用了set块,表示,如果该属性在被赋值时,会调用Adapter的notifyXX 方法来通知视图更新。

先介绍到这里,开发Android,写Java到很痛苦的小伙伴们,一起试试吧!

另外,Kotlin现在已经相对稳定,AndroidStudio (IntellJ Idea) 对Kotlin的支持相当好,毕竟是自家的东西。

有了val, 在也不用纠结 static final 和 final static 了。 :-)