Android 知识JetpackPack 知识Android 软件架构与软件架构

JetPack Compose 实战 Jetchat(1)

2021-06-24  本文已影响0人  zcwfeng

我们分析第一个开源代码,Jetcha app 一个聊天的例子。开始分析学习吧

这个例子我们能学习到下面的内容。

我的习惯是,先弄明白项目是如何构建,大概都需要什么

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对参数进行断言处理)

allWarningsAsErrors 将所有的警告当做错误处理,默认值为false
suppressWarnings 压制所有的警告,默认值为false
verbose 打印更多的信息,默认值为false
freeCompilerArgs 附加的编译器选项列表,默认值为[]

上一篇下一篇

猜你喜欢

热点阅读