我们分析第一个开源代码,Jetcha app 一个聊天的例子。开始分析学习吧
这个例子我们能学习到下面的内容。
- UI state management
- Integration with Architecture Components: Navigation, Fragments, ViewModel
- Back button handling
- Text Input and focus management
- Multiple types of animations and transitions
- Saved state across configuration changes
- Basic Material Design theming
- UI tests
我的习惯是,先弄明白项目是如何构建,大概都需要什么
project/build.gradle
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.example.compose.jetchat.buildsrc.Libs
import com.example.compose.jetchat.buildsrc.Urls
import com.example.compose.jetchat.buildsrc.Versions
buildscript {
ext.kotlin_version = '1.4.30'
ext.compose_version = '1.0.0-alpha12'
ext.coroutines_version = '1.4.2'
repositories {
google()
jcenter()
}
dependencies {
// classpath Libs.androidGradlePlugin
// classpath Libs.Kotlin.gradlePlugin
classpath 'com.android.tools.build:gradle:7.0.0-beta02'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id 'com.diffplug.spotless' version '5.10.0'
}
subprojects {
repositories {
google()
mavenCentral()
jcenter()
if (!Libs.AndroidX.Compose.snapshot.isEmpty()) {
maven { url Urls.composeSnapshotRepo }
maven { url Urls.accompanistSnapshotRepo }
}
}
apply plugin: 'com.diffplug.spotless'
spotless {
kotlin {
target '**/*.kt'
targetExclude("$buildDir/**/*.kt")
targetExclude('bin/**/*.kt')
ktlint(Versions.ktlint).userData([android: "true"])
licenseHeaderFile rootProject.file('spotless/copyright.kt')
}
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
// Treat all Kotlin warnings as errors
allWarningsAsErrors = true
freeCompilerArgs += '-Xopt-in=kotlin.RequiresOptIn'
// Enable experimental coroutines APIs, including Flow
freeCompilerArgs += '-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi'
freeCompilerArgs += '-Xopt-in=kotlinx.coroutines.FlowPreview'
freeCompilerArgs += '-Xopt-in=kotlin.Experimental'
// Set JVM target to 1.8
jvmTarget = "1.8"
}
}
}
看到前三行,我们就知道需要去看buildSrc
build.gradle.kts
repositories {
jcenter()
}
plugins {
`kotlin-dsl`
}
jcenter 即将关闭,不过不应想我们的学习,自然会换仓库,开源项目还在升级中。
使用Kotlin DSL构建Android项目
参考这个文章 构建项目从Groovy 过度到KTS
buildSrc/dependencies.kt
package com.example.compose.jetchat.buildsrc
object Versions {
const val ktlint = "0.40.0"
}
object Libs {
const val androidGradlePlugin = "com.android.tools.build:gradle:7.0.0-alpha05"
const val jdkDesugar = "com.android.tools:desugar_jdk_libs:1.0.9"
const val junit = "junit:junit:4.13"
const val material = "com.google.android.material:material:1.1.0"
object Kotlin {
private const val version = "1.4.30"
const val stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version"
const val gradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$version"
const val extensions = "org.jetbrains.kotlin:kotlin-android-extensions:$version"
}
object Coroutines {
private const val version = "1.4.2"
const val core = "org.jetbrains.kotlinx:kotlinx-coroutines-core:$version"
const val android = "org.jetbrains.kotlinx:kotlinx-coroutines-android:$version"
const val test = "org.jetbrains.kotlinx:kotlinx-coroutines-test:$version"
}
object Accompanist {
private const val version = "0.5.1"
const val insets = "dev.chrisbanes.accompanist:accompanist-insets:$version"
}
object AndroidX {
const val appcompat = "androidx.appcompat:appcompat:1.2.0-rc01"
const val coreKtx = "androidx.core:core-ktx:1.5.0-beta01"
object Activity {
const val activityCompose = "androidx.activity:activity-compose:1.3.0-alpha02"
}
object Compose {
const val snapshot = ""
const val version = "1.0.0-alpha12"
const val foundation = "androidx.compose.foundation:foundation:$version"
const val layout = "androidx.compose.foundation:foundation-layout:$version"
const val material = "androidx.compose.material:material:$version"
const val materialIconsExtended = "androidx.compose.material:material-icons-extended:$version"
const val runtime = "androidx.compose.runtime:runtime:$version"
const val runtimeLivedata = "androidx.compose.runtime:runtime-livedata:$version"
const val tooling = "androidx.compose.ui:ui-tooling:$version"
const val test = "androidx.compose.ui:ui-test:$version"
const val uiTest = "androidx.compose.ui:ui-test-junit4:$version"
const val uiUtil = "androidx.compose.ui:ui-util:${version}"
const val viewBinding = "androidx.compose.ui:ui-viewbinding:$version"
}
object Navigation {
private const val version = "2.3.3"
const val fragment = "androidx.navigation:navigation-fragment-ktx:$version"
const val uiKtx = "androidx.navigation:navigation-ui-ktx:$version"
}
object Test {
private const val version = "1.3.0"
const val core = "androidx.test:core:$version"
const val rules = "androidx.test:rules:$version"
object Ext {
private const val version = "1.1.2"
const val junit = "androidx.test.ext:junit-ktx:$version"
}
const val espressoCore = "androidx.test.espresso:espresso-core:3.3.0"
}
object Lifecycle {
private const val version = "2.3.0-beta01"
const val extensions = "androidx.lifecycle:lifecycle-extensions:$version"
const val livedata = "androidx.lifecycle:lifecycle-livedata-ktx:$version"
const val viewmodel = "androidx.lifecycle:lifecycle-viewmodel-ktx:$version"
const val viewModelCompose = "androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha01"
}
}
}
object Urls {
const val composeSnapshotRepo = "https://androidx.dev/snapshots/builds/" +
"${Libs.AndroidX.Compose.snapshot}/artifacts/repository/"
const val accompanistSnapshotRepo = "https://oss.sonatype.org/content/repositories/snapshots"
}
刚开始看,有点懵,但是仔细想象,这个和build.gradle其实异曲同工。如果你用gradle的groovy配置抽取到config.gradle也是一个逻辑。
Urls,Libs,Version 及时kt脚本定义的三个object实际上就是三个单利
在看,project 的build.gradle 脚本,开始熟悉了吧,知道折写变量哪里来的。
值得留意的是,他的gradle版本 com.android.tools.build:gradle:7.0.0-beta02
kotlin version 1.4.x 。 写这篇文章的时候,kotlin的稳定版是1.4.0
等过些日子就是1.5.0了。更新的很快。
com.diffplug.spotless
这个插件 是一个代码格式化工具,具体使用自行搜索一下。
allprojects是对所有project的配置,包括Root Project。而subprojects
是对所有Child Project的配置
kotlinOptions
为 Kotlin 项目设置编译选项
- 编译选项通常有以下这样的作用,不完全列举
开启或关闭某些feature等行为(比如coroutine, 新的类型推断算法等)
控制或设置编译器需要的参数(比如-jvm-target设置class的目标平台)
控制编译器的输出(比如method inline,-Xno-param-assertions对参数进行断言处理)
- 默认情况下,gradle中只有四个字段处理编译选项
allWarningsAsErrors 将所有的警告当做错误处理,默认值为false
suppressWarnings 压制所有的警告,默认值为false
verbose 打印更多的信息,默认值为false
freeCompilerArgs 附加的编译器选项列表,默认值为[]
网友评论