Kotlin

语言学习

Posted by LXG on July 2, 2025

使用 Kotlin 开发 Android 应用

为什么学习kotlin

层级 / 模块 Kotlin 使用情况
系统应用(Apps) ✅ 大量使用,如 Settings、SystemUI、Launcher3 等开始迁移到 Kotlin
Framework 层 🟡 部分引入,如 Jetpack 新 API 使用 Kotlin 编写
HAL / JNI / Native 层 ❌ 不使用 Kotlin,仍以 C/C++ 为主
核心服务(AMS/PMS 等) 🟡 主要为 Java,部分模块尝试 Kotlin 重构
构建系统 / 启动过程 ❌ 不使用 Kotlin,Make/C/Java 依旧为主

Kotlin 未能全面替代 Java 的原因

  • AOSP 中很多核心服务是早期大量用 Java 编写的(如 AMS、PMS、WMS 等),重构成本极高;
  • Java 对系统底层服务更稳定、兼容性更好;
  • 编译工具链、内存使用优化方面 Kotlin 在系统层仍有挑战;
  • Kotlin 增加了编译时依赖和运行时负担(如标准库、扩展库),这在 AOSP 的精简目标中是个顾虑。

AOSP 正在逐步引入 Kotlin 尤其是在系统应用层(Apps),但在 Framework 和核心服务中 Java 仍是主力语言,Kotlin 是渐进式替代而非整体迁移。

kotlin 对比 java

维度 Kotlin Java
语法简洁性 ✅ 更简洁(支持类型推导、默认参数等) ❌ 相对繁琐(代码冗长)
空指针安全 ✅ 内建 Null 安全系统 ❌ Null 是常见错误来源
扩展函数支持 ✅ 支持 ❌ 不支持
协程支持 ✅ 内置协程(轻量线程) ❌ 需要使用线程或第三方库
Lambda 表达式 ✅ 原生支持 ✅ Java 8+ 开始支持
数据类 ✅ 内建 data class ❌ 手写 getter、setter 等
默认不可变性 ✅ 推荐使用 val ❌ 默认可变
类型推导 ✅ 支持类型自动推导 ❌ 必须声明类型
枚举增强 ✅ 支持密封类、when ❌ 功能有限
Android 支持 ✅ 官方推荐语言 ✅ 老牌稳定语言
JVM 兼容性 ✅ 与 Java 完全互通 ✅ 与 Kotlin 可互通(公开 API)
编译速度 ⏳ 稍慢 ⚡ 更快
学习曲线 ⬆️ 稍陡峭 ✅ 容易上手
社区生态 ✅ 活跃增长中 ✅ 非常成熟

build.gradle 和 build.gradle.kts

特性 Groovy (build.gradle) Kotlin (build.gradle.kts)
类型安全 ❌ 弱类型 ✅ 强类型
自动补全与提示 ❌ 弱 ✅ 好(尤其在 Android Studio Arctic Fox+)
脚本灵活性 ✅ 高(支持较多 DSL 魔法) ⚠️ 限制较多,语法更严格
编写易用性 ✅ 语法宽松 ⚠️ 容易踩坑,尤其是早期版本 Gradle 插件
编译性能 ⚠️ 稍慢 ✅ 稍快(Gradle 7.0+ 表现更佳)
官方趋势 ✅ 兼容主流项目 ✅ Google 已推荐新项目使用 Kotlin DSL

settings.gradle.kts


pluginManagement {
    repositories {
        google()
        maven {
            url = uri("https://maven.aliyun.com/repository/gradle-plugin")
            content {
                includeGroupByRegex("com\\.android.*")
                includeGroupByRegex("com\\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        maven { url = uri("https://maven.aliyun.com/repository/public") }
        maven { url = uri("https://maven.aliyun.com/repository/google") }
        maven { url = uri("https://maven.aliyun.com/repository/jcenter") } // 已经废弃,仅用于老项目
        google()
        mavenCentral()
    }
}

rootProject.name = "AccessibilityDemo"
include(":app")

build.gradle.kts


// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.kotlin.android) apply false
    alias(libs.plugins.kotlin.compose) apply false
}

app/build.gradle.kts


plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
    alias(libs.plugins.kotlin.compose)
}

android {
    namespace = "com.wif.demo"
    compileSdk = 35

    defaultConfig {
        applicationId = "com.wif.demo"
        minSdk = 24
        targetSdk = 35
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = "11"
    }
    buildFeatures {
        compose = true
    }
}

dependencies {

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
}

gradle/libs.versions.toml


[versions]
agp = "8.10.1"
kotlin = "2.0.21"
coreKtx = "1.10.1"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
lifecycleRuntimeKtx = "2.6.1"
activityCompose = "1.8.0"
composeBom = "2024.09.00"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

关系图


libs.versions.toml
  │
  └──▶ 提供版本号和别名(比如 agp、kotlin、compose)
           │
           ▼
settings.gradle.kts
  ├── 设置插件仓库 pluginManagement { ... }
  ├── 设置依赖仓库 dependencyResolutionManagement { ... }
  └── include(":app") 指定模块
           │
           ▼
build.gradle.kts(每个模块)
  ├── 使用 plugins { alias(...) } 引入插件
  └── 使用 dependencies { implementation(...) } 引入依赖


基本语法

  1. 变量 val var
  2. 运算符 与java一致
  3. 字符串
  4. 字符串操作函数
  5. 模板表达式
  6. 条件语句
  7. when 字符,kotlin没有switch关键字
  8. 循环语句 while for
  9. 跳转语句 continue break
  10. 区间
  11. 数组
  12. 变量的类型转换
  13. 可空变量 非空变量
  14. ?: 操作符

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val int_a: Int = 1
        val Str_a: String = "hello"

        Log.d("LXG", Str_a)
        Log.d("LXG", "" + Str_a[3])

        val number: IntArray = intArrayOf(1, 2, 3, 4)
        var bool_array: BooleanArray = booleanArrayOf(true, true, false)
        var char_array: CharArray = charArrayOf('a', 'b')

        val int_array: Array<Int> = arrayOf(1, 2, 3)

        var string_array: Array<String> = arrayOf("hello", "world")

        
        var num1 = 1
        val s1 = "a is ${num1}"
        val s2 = "a is $num1"
        Log.d("LXG", "" + s1)
        Log.d("LXG", "" + s2)

        var month: Int = 7
        when(month) {
            12,1,2 -> println("冬季")
            3,4,5 -> println("春季")
            6,7,8 -> println("夏季")
            9,10,11 -> println("秋季")
            else -> println("未知")
        }

        var a: Int = 7
        var b: Int = 8
        when {
            a > b -> println("a 大于 b")
            a < b -> println("a 大于 b")
            else -> println("a 等于 b")
        }

        for (i in 0..3) {
            println("i = $i")
        }
        
        number.forEach { println(it.toString() + "\t") }

        string_array.forEachIndexed() {index, s -> println("index = $index , s = $s") }

        // 区间
        for (i in 1.rangeTo(4)) {
            println("i = $i")
        }

        for (i in 4.downTo(1)) {
            println("i = $i")
        }

        for (i in 4.downTo(1) step 2) {
            println("i = $i")
        }

        // 数组
        for ((index, i) in bool_array.withIndex()) {
            println("index = $index , s = $i")
        }
        println("4, index = " + number.indexOf(4))

        var name: String = "Tom" // 非空变量
        var telephone : String? = null
        var result = telephone?.length
        println(result)

    }

函数

  1. 函数定义
  2. 函数的类型
  3. 单表达式函数
  4. 函数的参数
  5. 可变参数 vararg
  6. 函数的分类:顶层函数 成员函数 局部函数 递归函数
  7. 函数重载

    fun doubleValue(x:Int): Int {
        return x * 2
    }

    // 单表达式函数
    // private fun doubleValue(x:Int): Int = x * 2

    fun sum(name:String, vararg scores:Int) {
        var result = 0
        scores.forEach { result += it }
        println(name + "总成绩: "+ result)
    }

面向对象

  1. 类的定义
  2. 对象的创建
  3. 类的封装
  4. 类的继承
  5. 方法重写
  6. super关键字
  7. Any类和Object类
  8. 抽象类
  9. 接口
  10. 嵌套类(内部类 inner关键字)
  11. 枚举类
  12. 密封类
  13. 数据类
  14. 单例模式
  15. 伴生对象
  16. 类委托 属性委托 关键字 by
  17. 延迟加载 by lazy
  18. 异常

package com.wif.kotlindemo

abstract class Animal {
    abstract fun eat()
}

interface Monkey {
    fun sleep()
}

object  Singleton {
    var name = "单例模式"
    fun sayHello() {
        println("hello")
    }
}

class Person : Animal(), Monkey {

    private var name = "wif"
    private val age = 0

    fun sayHello() {
        println("hello")
    }

    override fun eat() {
        println("monkey eat")
    }

    override fun sleep() {
        println("monkey sleep")
        Singleton.sayHello()
    }

}

集合

  1. Collection: List Set MutableCpllection
  2. Map: HashMap TreeMap MutableMap
  3. 不可变List: 查询 批量包含 检索 编历
  4. 可变MutableList
  5. 不可变Set
  6. 可变MutableSet
  7. 不可变Map
  8. 可变MutableMap

        // 不可变List
        val list: List<Int> = listOf(1, 2, 3, 4, 5)
        if (list.contains(3)) {
            println("包含3")
        }

        val mIndex = list.iterator()
        while (mIndex.hasNext()) {
            println(mIndex.next().toString() + "\t")
        }

        // 可变List
        val muList: MutableList<Int> = mutableListOf(1, 2, 3, 4, 5)
        muList.add(6)
        muList.remove(1)
        muList.set(1, 7)
        muList.forEach { println(it.toString() + "\t") }

        // 不可变集合
        val set: Set<Int> = setOf(1, 2, 3, 4, 5)
        val setIndex = set.iterator()
        while (mIndex.hasNext()) {
            println(setIndex.next().toString() + "\t")
        }

        // 可变集合
        val muSet: MutableSet<Int> = mutableSetOf(1, 2, 3, 4, 5)
        muSet.add(6)
        muSet.remove(1)
        muSet.forEach { println(it.toString() + "\t") }
        println(muSet)

        // 不可变Map
        val map = mapOf(1 to "one", 2 to "two", 3 to "three")
        map.forEach { println(it.key.toString() + ":" + it.value) }
        val mapKey = map.keys
        val mapValue = map.values
        val mapEntry = map.entries
        mapEntry.forEach { println(it.key.toString() + ":" + it.value) }

        // 可变Map
        val muMap = mutableMapOf(1 to "one", 2 to "two", 3 to "three")
        muMap.put(4, "four")
        muMap.remove(1)
        muMap.forEach { println(it.key.toString() + ":" + it.value) }

Lambda编程

Lambda 表达式就是一个匿名函数,它是函数式编程的基础,函数式编程的思想是将计算机运算视为函数的计算,并且计算的函数可以接收函数作为输入参数或者返回值

  1. 无参数有返回值
  2. 有参数有返回值
  3. 返回值:返回值的类型和值是最后一条语句决定的
  4. 高阶函数
  5. 扩展函数
  6. kotlin 和 java 很大的一个区别就是函数的用法,kotlin要灵活的多
  7. 函数作为返回值
  8. 标准库中的高阶函数
  9. 内联函数

        run { println("lambda") }

        var sumInt = {
            a:Int, b:Int -> a + b
        }
        println(sumInt(6,8))

        // 高阶函数
        val listNew = 1..20
        println("能被5整除的数")
        println(listNew.picNum { it -> it % 5 == 0 })
        println("能被10整除的数")
        println(listNew.picNum { it -> it % 10 == 0 })

        // 函数作为返回值
        val normalUserPrice = getPrice(USER.NORMAL)(200.0)
        println("普通用户价格: $normalUserPrice")
        val vipPrice = getPrice(USER.VIP)(200.0)
        println("超级会员价格: $vipPrice")

        // 标准库中的高阶函数
        println("找出等于3的元素:${list.find { it == 3 }}")
        println("第一个等于3的元素:${list.first { it == 3 }}")
        println("最后一个找出等于3的元素:${list.last { it == 3 }}")


    // 给区间定义一个扩展方法
    fun IntRange.picNum(function: (Int)->Boolean): List<Int> {
        val list = mutableListOf<Int>()
        for (i in this) {
            if (function(i)) {
                list.add(i)
            }
        }
        return list
    }

    enum class USER {
        NORMAL, VIP, ADMIN
    }

    fun getPrice(userType: USER): (Double) -> Double {
        if (userType == USER.NORMAL) {
            return {it}
        }
        return { price -> 0.88 * price}
    }

泛型

泛型是一种编译时的安全检测机制,允许定义类,接口,方法时使用类型参数,声明的类型参数在使用时用具体的类型来替换。泛型的本质是参数化类型

泛型编程是提升代码复用性与类型安全的强大工具,适合构建通用库与抽象框架,但在一些语言中存在类型擦除、可读性和调试困难等挑战。

  1. 泛型的定义
  2. 泛型的分类:泛型类
  3. 自定义泛型类
  4. 泛型接口
  5. 泛型方法
  6. 自定义泛型方法
  7. 泛型约束
  8. 字类和字类型
  9. 协变和逆变
  10. 泛型擦除和实化类型

    class Box<T>(t:T) {
        var value = t
    }


    val box: Box<Int> = Box<Int>(10)
    val box2 = Box(10)

    // 泛型类
    val list = ArrayList<Int>()
    val map = HashMap<String, Int>()

    // 自定义泛型类
    class Box<T>() {
        var t: T? = null

        fun add(t: T) {
            this.t = t
        }

        fun get(): T? {
            return t
        }
    }

    data class Apple(val name: String)

    fun demo() {
        val box = Box<Apple>()
        box.add(Apple("Apple"))
        val apple = box.get()
        println(apple?.name)
    }

    // 泛型接口
    interface List<E> : Collection<E> {
        fun get(index: Int): E
        fun set(index: Int, element: E): E
        fun add(element: E): Boolean
        fun add(index: Int, element: E): Boolean
        fun remove(element: E): Boolean
        fun indexOf(element: E): Int
        fun lastIndexOf(element: E): Int
        fun listIterator(): ListIterator<E>
        fun listIterator(index: Int): ListIterator<E>
        fun subList(fromIndex: Int, toIndex: Int): List<E>
    }


    //自定义泛型方法
    fun <T> printInfo(content: T) {
        when(content) {
            is Int -> println("Int")
            is String -> println("String")
            is Double -> println("Double")
            else -> println("Other")
        }
    }

协程

协程是将复杂的异步操作放入底层库中,程序逻辑在协程中按照顺序表达,底层库将用户代码包装为回调/订阅事件,主要有以下两个特点:

  • 协程挂起
  • 简化代码

import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        lifecycleScope.launch {
            delay(1000)
            println("延迟1秒")   // 需要注意:此打印仍在主线程中,所以协程和线程是有差异的
        }
    
        println("onCreate end")
    }

}