美文网首页kotlinAndroid开发之路其他
说那么多干嘛,直接用kotlin写项目吧

说那么多干嘛,直接用kotlin写项目吧

作者: 间歇性丶神经病患者 | 来源:发表于2017-06-26 09:43 被阅读756次

    Kotlin 与 Android

    什么是Kotlin?

    Kotlin,它是JetBrains开发的基于JVM的语言。JetBrains因为创造了一个强大的Java开发IDE被大家所熟知。Android Studio,官方的Android IDE,就是基于Intellij,作为一个该平台的插件。
    Kotlin是使用Java开发者的思维被创建的,Intellij作为它主要的开发IDE。对于Android开发者,有两个有趣的特点:
    对Java开发者来说,Kotlin是非常直觉化的,并且非常容易学习。语言的大部分内容都是与我们知道的非常相似,不同的地方,它的基础概念也能迅速地掌握它。
    它与我们日常生活使用的IDE无需配置就能完全整合。Android Studio能够非常完美地理解、编译运行Kotlin代码。而且对这门语言的支持来正是自于开发了这个IDE的公司本身,所以我们Android开发者是一等公民。
    但是这仅仅是开发语言和开发工具之间的整合。相比Java 7的优势到底是什么呢?

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

    Kotlin的用途

    服务器端

    使用 Kotlin 进行服务器端开发
    Kotlin 非常适合开发服务器端应用程序,允许编写简明且表现力强的代码, 同时保持与现有
    基于 Java 的技术栈的完全兼容性以及平滑的学习曲线:
    表现力: Kotlin 的革新式语言功能,例如支持类型安全的构建器和委托属性,有助于构建
    强大而易于使用的抽象。
    可伸缩性: Kotlin 对协程的支持有助于构建服务器端应用程序, 伸缩到适度的硬件要求
    以应对大量的客户端。
    互操作性: Kotlin 与所有基于 Java 的框架完全兼容,可以让你保持熟悉的技术栈,同时
    获得更现代化语言的优势。
    迁移: Kotlin 支持大型代码库从 Java 到 Kotlin 逐步迁移。你可以开始用 Kotlin 编写新代
    码,同时系统中较旧部分继续用 Java。
    工具: 除了很棒的 IDE 支持之外,Kotlin 还为 IntelliJ IDEA Ultimate 的插件提供了框架特
    定的工具(例如 Spring)。
    学习曲线: 对于 Java 开发人员,Kotlin 入门很容易。包含在 Kotlin 插件中的自动 Java
    到 Kotlin 的转换器有助于迈出第一步。Kotlin 心印 通过一系列互动练习提供了语言主要
    功能的指南。

    服务器推荐的框架

    Spring 利用 Kotlin 的语言功能提供更简洁的 API, 从版本 5.0 开始。在线项目生成器允
    许用 Kotlin 快速生成一个新项目。
    Vert.x 是在 JVM 上构建响应式 Web 应用程序的框架, 为 Kotlin 提供了专门支持,包括
    完整的文档。
    Ktor 是由 JetBrains 构建的 Kotlin 原生 Web 框架,利用协程实现高可伸缩性,并提供易
    于使用且合乎惯用法的 API。
    kotlinx.html 是可在 Web 应用程序中用于构建 HTML 的 DSL。 它可以作为传统模板系统
    (如JSP和FreeMarker)的替代品。
    通过相应 Java 驱动程序进行持久化的可用选项包括直接 JDBC 访问、JPA 以及使用
    NoSQL 数据库。 对于 JPA,kotlin-jpa 编译器插件使 Kotlin 编译的类适应框架的要求。
    ktor - 用 Kotlin 写的 Web 后端开发框架
    Kara - MVC 开发框架
    Yested - 用来开发 SPA 应用的框架
    HEXAGON- 微服务框架

    Android 端

    Kotlin 非常适合开发 Android 应用程序,将现代语言的所有优势带入 Android 平台而不会引入
    任何新的限制:
    兼容性:Kotlin 与 JDK 6 完全兼容,保障了 Kotlin 应用程序可以在较旧的 Android 设备
    上运行而无任何问题。Kotlin 工具在 Android Studio 中会完全支持,并且兼容 Android 构
    建系统。
    性能:由于非常相似的字节码结构,Kotlin 应用程序的运行速度与 Java 类似。 随着
    Kotlin 对内联函数的支持,使用 lambda 表达式的代码通常比用 Java 写的代码运行得更
    快。
    互操作性:Kotlin 可与 Java 进行 100% 的互操作,允许在 Kotlin 应用程序中使用所有现
    有的 Android 库 。这包括注解处理,所以数据绑定和 Dagger 也是一样。
    占用:Kotlin 具有非常紧凑的运行时库,可以通过使用 ProGuard 进一步减少。 在实际
    应用程序中,Kotlin 运行时只增加几百个方法以及 .apk 文件不到 100K 大小。
    编译时长:Kotlin 支持高效的增量编译,所以对于清理构建会有额外的开销,增量构建通
    常与 Java 一样快或者更快。
    学习曲线:对于 Java 开发人员,Kotlin 入门很容易。包含在 Kotlin 插件中的自动 Java
    到 Kotlin 的转换器有助于迈出第一步。Kotlin 心印 通过一系列互动练习提供了语言主要
    功能的指南。

    Android 推荐使用的工具

    Kotlin Android 扩展是一个编译器扩展, 可以让你摆脱代码中的 findViewById() 调用,
    并将其替换为合成的编译器生成的属性。
    Anko 是一个提供围绕 Android API 的 Kotlin 友好的包装器的库,以及一个可以用 Kotlin
    Kotlin 用于 Android 代码替换布局 .xml 文件的 DSL。
    KAndroid - Kotlin library for Android
    Bubble - 屏幕方向监测
    Kotpref -android sp缓存工具
    Fuese - android内存缓存工具
    Kotter Knife KotlinPoet 类似黄油刀的依赖注入框架
    Klaxon 一个解析 JSON 的库

    Kotlin 与 JavaScript

    Kotlin 提供了 JavaScript 作为目标平台的能力。它通过将 Kotlin 转换为 JavaScript 来实现。
    目前的实现目标是 ECMAScript 5.1,但也有最终目标为 ECMAScript 2015的计划。
    当你选择 JavaScript 目标时,作为项目一部分的任何 Kotlin 代码以及 Kotlin 附带的标准库都
    会转换为 JavaScript。 但是,这不包括使用的 JDK 和任何 JVM 或 Java 框架或库。任何不是
    Kotlin 的文件会在编译期间忽略掉。
    Kotlin 编译器努力遵循以下目标:
    提供最佳大小的输出
    提供可读的 JavaScript 输出
    提供与现有模块系统的互操作性
    在标准库中提供相同的功能,无论是 JavaScript 还是 JVM 目标(尽最大可能程度)。

    怎么使用kotlin(环境搭建)

    IDEA:

    Kotlin版本从2015年开始就与IntelliJ IDEA捆绑在一起,

    1. 在安装IntelliJ IDEA后,打开它并创建一个新项目。选择菜单:【File】->【New Project】,Java Module并选择SDK,Kotlin要与JDK 1.6+一起使用。 另外,选择Kotlin(Java)复选框。


      image.png
    2. 点击finish就可以,如下图:


      image.png

    AndroidStudio

    好吧,其实IDEA怎么搭建环境不关我什么事,as搭建环境才是关我事情的

    1. 安装Kotlin的插件:


      image.png
    1. 把项目转换为kotlin项目:


      image.png
    1. 新建好的MainActivity.java, 注意这里是.java后缀的java文件,我们可以手动转换为kotlin代码


      image.png
    image.png

    4,转换后得到了一个MainActivity.kt,


    image.png

    到了这一步我们就拿到了一个原汁原味的kotlin项目了。

    image.png

    基本的语法:

    基本类型:

    数字

    image.png

    定义数字:

    var aInt:Int=1
    var bDouble:Double=12.5
    var fFloat=12.4f
    

    每个数字类型支持如下的转换:

    
    toByte(): Byte
    toShort(): Short
    toInt(): Int
    toLong(): Long
    toFloat(): Float
    toDouble(): Double
    toChar(): Char
    
    

    也可以有隐式的转换:

    val l = 1L + 3 // Long + Int => Long
    

    也支持运算符:

    这是完整的位运算列表(只用于 Int 和 Long ):
    shl(bits) – 有符号左移 (Java 的 << )
    shr(bits) – 有符号右移 (Java 的 >> )
    ushr(bits) – 无符号右移 (Java 的 >>> )
    and(bits) – 位与
    or(bits) – 位或
    xor(bits) – 位异或
    基本类型
    56
    inv() – 位非
    

    字符

    字符用 Char 类型表示。它们不能直接当作数字

    我们可以显式把字符转换为 Int 数字:

    fun decimalDigitValue(c: Char): Int {
    if (c !in '0'..'9')
    throw IllegalArgumentException("Out of range")
    return c.toInt() - '0'.toInt() // 显式转换为数字
    }
    
    

    其他的就没什么了.....不讲了

    控制流

    if else

    在 Kotlin 中, if 是一个表达式,即它会返回一个值。 因此就不需要三元运算符(条件 ? 然
    后 : 否则),因为普通的 if 就能胜任这个角色。

    eg. 有一个int值是a,一个int值是b,求他们的比较大的那个数

    java

    
     int a = 1, b = 3;
     Log.e("a和b的最大值是", a > b ? a + "" : b + "");
    
    

    kotlin

     val a:Int=1
     val b:Int=3
     val max = if (a > b) a else b
     print("a和b里面最大的是"+max)
    

    When 表达式

    when 将它的参数和所有的分支条件顺序比较,直到某个分支满足条件。 when 既可以被当
    做表达式使用也可以被当做语句使用。如果它被当做表达式, 符合条件的分支的值就是整个
    表达式的值,如果当做语句使用, 则忽略个别分支的值。(像 if 一样,每一个分支可以是
    一个代码块,它的值是块中最后的表达式的值。)
    如果其他分支都不满足条件将会求值 else 分支。 如果 when 作为一个表达式使用,则必须
    有 else 分支, 除非编译器能够检测出所有的可能情况都已经覆盖了。

    eg. 实例demo里面的适配器代码:

    
      when (dataItem.type) {
                "Android" -> holder?.ivType?.setImageResource(R.mipmap.android_icon)
                "iOS" -> holder?.ivType?.setImageResource(R.mipmap.ios_icon)
                "前端" -> holder?.ivType?.setImageResource(R.mipmap.js_icon)
                "拓展资源" -> holder?.ivType?.setImageResource(R.mipmap.other_icon)
                else -> holder?.ivType?.setImageResource(R.mipmap.android_icon)
            }
    
    

    For 循环

    for 循环可以对任何提供迭代器(iterator)的对象进行遍历,语法如下:

    
    for (item in collection) print(item)
    
    

    While 循环

    循环中的Break和continue

    --- --- 可以参考下我后面发出来的文档

    定义一个类:

    类声明由类名类头(指定其类型参数、主构造函数等)和由大括号包围的类体构成。类头
    和类体都是可选的; 如果一个类没有类体,可以省略花括号。

    
    class Person constructor(firstName: String) {
    }
    
    

    构造函数

    在 Kotlin 中的一个类可以有一个主构造函数和一个或多个次构造函数。主构造函数是类头的
    一部分:它跟在类名(和可选的类型参数)后。

    class Person constructor(firstName: String) {
    }
    
    

    如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。

    class Person(firstName: String) {
    }
    

    定义一个构造函数的函数体:

    class Person(name: String, surname: String) {
        init{
            ...
        }
    }
    

    很复杂...看懵了,不管了 我们看个例子:

    
    /**
     * Created by Ly on 2017/6/23.
     */
    open class Person(var age: Int, var name: String) {
        fun sayName(): String {
            return name
        }
        fun sayAge(): Int {
            return age
        }
    }
    fun main(args: Array<String>) {
        val person = Person(11, "Ly")
        print(person.sayName()+" is "+person.sayAge())
    }
    
    

    打印结果如下:

    image.png

    修改代码

    
    open class Person(var age: Int, var name: String) {
    
        init {
            name="Lht"
            age=24
        }
        fun sayName(): String {
            return name
        }
        fun sayAge(): Int {
            return age
        }
    }
    fun main(args: Array<String>) {
        val person = Person(11, "Ly")
        print(person.sayName()+" is "+person.sayAge())
    }
    
    

    打印结果:

    image.png

    eg. Android 适配器的ViewHolder类(java 代码)

    
      public static class ViewHolder extends RecyclerView.ViewHolder {
            @BindView(R.id.iv_girl)
            ImageView ivGirl;
            public ViewHolder(View itemView) {
                super(itemView);
                KnifeKit.bind(this, itemView);
            }
        }
    
    
    

    Android适配器的ViewHolder类(Kotlin代码)

    
        inner class GirlHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            internal var ivGril: ImageView = itemView.findViewById(R.id.iv_girl)
        }
    
    

    Android适配器的ViewHolder类(Kotlin代码 不用缩写 使用init初始化方法)

    
     inner class HomeHolder(item: View) : RecyclerView.ViewHolder(item) {
            internal var ivType: ImageView
            internal var tvType: TextView
            internal var ivAuthor: ImageView
            internal var tvAuthor: TextView
            internal var tvTime: TextView
            internal var rlMessage: RelativeLayout
            internal var ivPart: ImageView
            internal var ivVedio: ImageView
            internal var tvItem: TextView
    
            init {
                ivType = itemView.findViewById<ImageView>(R.id.iv_type)
                tvType = itemView.findViewById<TextView>(R.id.tv_type)
                ivAuthor = itemView.findViewById<ImageView>(R.id.iv_author)
                tvAuthor = itemView.findViewById<TextView>(R.id.tv_author)
                tvTime = itemView.findViewById<TextView>(R.id.tv_time)
                rlMessage = itemView.findViewById<RelativeLayout>(R.id.rl_message)
                ivPart = itemView.findViewById<ImageView>(R.id.iv_part)
                ivVedio = itemView.findViewById<ImageView>(R.id.iv_vedio)
                tvItem = itemView.findViewById<TextView>(R.id.tv_item)
            }
        }
    
    

    class的继承:

    默认下任何类都是继承自Any( 类似 java中的Object,但是Any 不是 java.lang.Object ;尤其是,它除了 equals() 、 hashCode() 和 toString() 外没有任何成员) ,但是我们可以继承其它类。
    所有的类默认都是不可继承的(final),所以我们只能继承那些明确声明open或者abstract的类:

    image.png
    open class Animal(name: String)
    class Person(name: String, surname: String) : Animal(name)
    

    当我们只有单个构造器时,我们需要在从父类继承下来的构造器中指定需要的参数。这是用来替换Java中的super调用的。
    其实就是super()

    字段和属性

    类里面有属性,属性可以用关键字 var 声明为可变的,否则使用只读关键字 val

    kotlin中的函数:

    函数(方法)可以使用fun关键字进行定义:

    fun onCreate(savedInstanceState: Bundle?) {
    }
    

    如果你没有指定它的返回值,它就会返回Unit,与Java中的void类似,但是Unit是一个真正的对象。你当然也可以指定任何其它的返回类型:

    fun add(x: Int, y: Int) : Int {
        return x + y
    }
    

    然而如果返回的结果可以使用一个表达式计算出来,你可以不使用括号而是使用等号:

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

    我们可以给参数指定一个默认值使得它们变得可选

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

    这个给我的感觉就类似这个:

     @RequestMapping(value = "updateType")
    public String updateType(
     @RequestParam(value = "typeId", defaultValue = "", required = false) Integer typeId,
     @RequestParam(value = "typeName", defaultValue = "", required = false) String typeName,
     @RequestParam(value = "flag", defaultValue = "1", required = false) Integer flag,
     @RequestParam(value = "type", required = false) Integer typeAttributes,
     HttpServletRequest request, Model model) {
    

    kotlin中的接口:

    android的接口一般用于做回调地狱

       interface ItemClickListener {
            fun onItemClickListener(url:String)
        }
    

    使用点击事件回调地狱

    
      girlAdapter?.setOnItemClickListener(object : GirlAdapter.ItemClickListener {
                override fun onItemClickListener(url: String) {
                    val intent = Intent()
                    val bun = Bundle()
                    bun.putString("url", url)
                    //获取intent对象
                    intent.setClass(activity, SeeBeautyActivity::class.java)
                    // 获取class是使用::反射
                    intent.putExtra("extra", bun)
                    startActivity(intent)
                }
            })
    
    

    kotlin 中的内部类

    使用inner关键字

    
    /**
     * Created by Ly on 2017/6/23.
     * 美女合集适配器
     */
    class GirlAdapter(context: Context) : RecyclerView.Adapter<GirlHolder>() {
        private var data = ArrayList<GankResults.Item>()
        private var context: Context = context
        private var onItemClickListener: ItemClickListener? = null
        fun setOnItemClickListener(onItemClickListener: ItemClickListener) {
            this.onItemClickListener = onItemClickListener
        }
    
        fun setData(data: List<GankResults.Item>) {
            this.data.clear()
            this.data.addAll(data)
            notifyDataSetChanged()
        }
    
        fun addData(data: List<GankResults.Item>) {
            this.data.addAll(data)
            notifyDataSetChanged()
        }
    
        override fun onBindViewHolder(holder: GirlHolder?, position: Int) {
            Glide.with(context).load(data[position].url).into(holder?.ivGirl)
            holder?.itemView?.setOnClickListener {
                onItemClickListener?.onItemClickListener(data[position].url)
            }
        }
    
        override fun getItemCount(): Int = data.size
    
        override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): GirlHolder {
            return GirlHolder(LayoutInflater.from(context).inflate(R.layout.adapter_gril, parent, false))
        }
    
        inner class GirlHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            internal var ivGirl: ImageView = itemView.findViewById(R.id.iv_girl)
        }
    
        interface ItemClickListener {
            fun onItemClickListener(url:String)
        }
    }
    
    

    OK 大概了解了kotlin以后,我们进入正题,kotlin与android

    划重点:

    1. 和Java的无缝调用,说明我们使用kotlin代码也可以随意使用目前所有的第三方java语言的sdk
    2. 大量的语法糖,例如Toast 吐司
    3. 更加安全,Kotlin 并不存在NullPointException
    4. RxKotlin

    按着两个项目对比讲,主要讲区别 以及anko

    OK,开始之前,我们先看两个demo项目:
    https://github.com/LinHuanTanLy/JavaDemo
    https://github.com/LinHuanTanLy/KotlinDemo

    image.png image.png

    相关文章

      网友评论

      本文标题:说那么多干嘛,直接用kotlin写项目吧

      本文链接:https://www.haomeiwen.com/subject/ldudcxtx.html