Android Kotlin使用详解

Kotlin 已成为 Android 开发的官方首选语言,它结合了面向对象和函数式编程的特性,提供了更简洁、安全和高效的开发体验。下面我将从基础到高级全面介绍 Kotlin 在 Android 开发中的应用。

一、Kotlin 基础语法

1. 变量声明

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 可变变量
var count: Int = 10
count = 15

// 不可变变量
val name: String = "Kotlin"
// name = "Java" // 编译错误

// 类型推断
val message = "Hello" // 自动推断为String类型

2. 空安全设计

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var nullableString: String? = null // 可空类型
var nonNullString: String = "text" // 非空类型

// 安全调用
val length = nullableString?.length // 返回Int?

// Elvis操作符
val len = nullableString?.length ?: 0 // 如果为null则返回0

// 非空断言(慎用)
val forcedLength = nullableString!!.length // 可能抛出NPE

3. 函数定义

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 基本函数
fun sum(a: Int, b: Int): Int {
    return a + b
}

// 表达式函数体
fun sum(a: Int, b: Int) = a + b

// 默认参数
fun greet(name: String = "World") {
    println("Hello, $name!")
}

// 命名参数
greet(name = "Kotlin")

4、标准库函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//apply 使用:函数在对象的上下文中执行代码块,并返回对象本身
val person = Person().apply {
    name = "Alice"
    age = 25
    city = "New York"
}

// let的使用:作用域使用it代表对象访问其属性,通常结合?使用,对象非空才执行作用域。返回值为最后一行
val result = someObject?.let {
    // 处理非空对象
    it.doSomething()
    transform(it)
}

// with的使用:传入对象,可以直接引用对象的公有方法或者公有属性,返回值为函数最后一行
val people = People("carson", 25)
with(people) {
    println("my name is $name, I am $age years old")
}

// run的使用:let和with的结合作用域,返回值为最后一行
val people = People("carson", 25)
people?.run{
    println("my name is $name, I am $age years old")
}

二、Kotlin 面向对象编程

1. 类与对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 简单类
class Person(val name: String, var age: Int) {
    // 次构造函数
    constructor(name: String) : this(name, 0)
    
    // 方法
    fun speak() {
        println("$name is speaking")
    }
}

// 使用
val person = Person("Alice", 25)
person.age = 26

2. 数据类 (Data Class)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
data class User(
    val id: Long,
    val name: String,
    val email: String
)

// 自动生成:
// equals()/hashCode()
// toString()
// copy()
// componentN()函数

3. 单例对象 (Object)

1
2
3
4
5
6
7
8
object Singleton {
    fun doSomething() {
        println("Doing work")
    }
}

// 使用
Singleton.doSomething()

4. 伴生对象 (Companion Object)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class MyClass {
    companion object {
        const val CONSTANT = "value"
        
        fun create(): MyClass = MyClass()
    }
}

// 使用
val instance = MyClass.create()

三、Kotlin 函数式编程特性

1. Lambda 表达式

1
2
3
4
5
val sum = { x: Int, y: Int -> x + y }
println(sum(1, 2)) // 输出3

// 作为参数
list.filter { it > 0 }

2. 高阶函数

1
2
3
4
5
6
fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
    return operation(x, y)
}

// 使用
val result = calculate(10, 5) { a, b -> a * b }

3. 集合操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
val numbers = listOf(1, 2, 3, 4, 5)

// 转换
val doubled = numbers.map { it * 2 }

// 过滤
val evens = numbers.filter { it % 2 == 0 }

// 查找
val firstEven = numbers.first { it % 2 == 0 }

// 分组
val grouped = numbers.groupBy { if (it % 2 == 0) "even" else "odd" }

四、Kotlin 与 Android 开发

1. 扩展函数 (Extension Functions)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 为View添加扩展函数
fun View.show() {
    visibility = View.VISIBLE
}

fun View.hide() {
    visibility = View.GONE
}

// 使用
view.show()

2. Android KTX 扩展

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 使用KTX简化SharedPreferences
val sharedPref = activity.preferences
sharedPref.edit { 
    putBoolean("key", true)
}

// 简化Fragment事务
supportFragmentManager.commit {
    replace(R.id.container, MyFragment())
    addToBackStack(null)
}

3. View Binding 与 Kotlin

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// build.gradle
android {
    viewBinding {
        enabled = true
    }
}

// Activity中使用
private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)
    
    binding.textView.text = "Hello Kotlin"
}

五、Kotlin 协程 (Coroutines)

1. 基本使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 在ViewModel中
fun loadData() {
    viewModelScope.launch {
        // 在主线程执行
        val result = withContext(Dispatchers.IO) {
            // 在IO线程执行网络请求
            repository.fetchData()
        }
        // 自动切换回主线程
        _uiState.value = UiState.Success(result)
    }
}

2. 结合 Retrofit

1
2
3
4
5
6
7
8
9
interface ApiService {
    @GET("users/{id}")
    suspend fun getUser(@Path("id") id: String): User
}

// Repository中
suspend fun getUser(id: String): User {
    return apiService.getUser(id)
}

3. 流处理 (Flow)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
fun getDataStream(): Flow<Data> = flow {
    repeat(10) {
        delay(1000)
        emit(fetchData())
    }
}

// 收集流
lifecycleScope.launch {
    getDataStream()
        .flowOn(Dispatchers.IO)
        .catch { e -> handleError(e) }
        .collect { data ->
            updateUI(data)
        }
}

六、Kotlin 与 Jetpack 组件

1. ViewModel

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class MyViewModel : ViewModel() {
    private val _data = MutableLiveData<String>()
    val data: LiveData<String> = _data
    
    fun loadData() {
        viewModelScope.launch {
            _data.value = repository.loadData()
        }
    }
}

2. Room 数据库

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
@Entity
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo val firstName: String,
    @ColumnInfo val lastName: String
)

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): Flow<List<User>>
    
    @Insert
    suspend fun insert(user: User)
}

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

3. WorkManager

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class UploadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {
    
    override suspend fun doWork(): Result {
        return try {
            uploadData()
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }
}

// 调度工作
val uploadRequest = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
    )
    .build()

WorkManager.getInstance(context).enqueue(uploadRequest)

七、Kotlin 高级特性

1. 密封类 (Sealed Class)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
sealed class Result<out T> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

// 使用
when (result) {
    is Result.Success -> showData(result.data)
    is Result.Error -> showError(result.exception)
    Result.Loading -> showProgress()
}

2. 内联类 (Inline Class)

1
2
3
4
5
6
7
8
@JvmInline
value class Password(val value: String) {
    init {
        require(value.length >= 8) { "密码太短" }
    }
}

// 运行时只保留String,无额外对象分配

3. 委托属性 (Delegated Properties)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 惰性初始化
val lazyValue: String by lazy {
    println("计算值")
    "Hello"
}

// 观察属性变化
var observableValue: String by Delegates.observable("初始值") { 
    prop, old, new ->
    println("$old -> $new")
}

// View Binding委托
private val binding by viewBinding(ActivityMainBinding::inflate)

八、Kotlin 性能优化

  1. 使用 val 代替 var:尽可能使用不可变变量
  2. 内联函数:对高阶函数使用 inline 关键字减少运行时开销
  3. 避免自动装箱:使用基本类型集合如 IntArray 代替 Array<Int>
  4. 谨慎使用伴生对象:伴生对象会生成额外的类
  5. 合理使用协程:避免创建过多不必要的协程

九、Kotlin 与 Java 互操作

1. Java 调用 Kotlin

1
2
3
4
5
6
7
8
// Kotlin
object KotlinUtils {
    @JvmStatic
    fun greet(name: String) = println("Hello, $name")
}

// Java调用
KotlinUtils.greet("Java");

2. Kotlin 调用 Java

1
2
3
4
5
6
7
8
9
// Java类
public class JavaUtils {
    public static String getMessage() {
        return "From Java";
    }
}

// Kotlin调用
val message = JavaUtils.getMessage()

3. 空安全与 Java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 使用平台类型注解
@Nullable
public String getNullableString() { /*...*/ }

@NotNull
public String getNonNullString() { /*...*/ }

// Kotlin中
val nullable: String? = getNullableString()
val nonNull: String = getNonNullString()

十、Kotlin 开发最佳实践

  1. 遵循编码规范:使用官方 Kotlin 代码风格
  2. 利用标准库函数:如 let, apply, run, also, takeIf
  3. 优先使用不可变数据:减少副作用
  4. 合理使用扩展函数:增强可读性但避免过度使用
  5. 编写单元测试:充分利用 Kotlin 的表达能力编写简洁的测试
  6. 持续学习新特性:Kotlin 语言在不断进化

总结

Kotlin 为 Android 开发带来了诸多优势:

  • 简洁性:减少样板代码,提高开发效率
  • 安全性:空安全设计减少 NPE
  • 互操作性:与 Java 100% 互操作
  • 现代特性:协程、扩展函数等现代化语言特性
  • 官方支持:Google 官方推荐的 Android 开发语言

通过掌握 Kotlin 的各种特性和最佳实践,开发者可以构建更健壮、高效和可维护的 Android 应用。

Built with Hugo
主题 StackJimmy 设计