Android架构师

组织 Android 依赖项的最佳方法

2022-07-29  本文已影响0人  程序员DS

我们都工作过或至少见过一个带有 build.gradle 文件的项目,它看起来像这样

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.0.3"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    kapt "androidx.lifecycle:lifecycle-compiler:2.1"
    implementation "androidx.room:room-runtime:1.3"
    kapt "androidx.room:room-compiler:$room_version"
    implementation "com.google.android.material:material:1.0.0-rc01"
    implementation "androidx.cardview:cardview:1.0.0"
    implementation "org.jetbrains.anko:anko-commons:0.10.4"
    implementation 'com.android.support:design:23.1.1'
    implementation 'com.jakewharton:butterknife:7.0.1'
    implementation 'com.jakewharton.timber:timber:4.1.0'
    implementation 'com.squareup.retrofit2:retrofit:2.0.0'
    testImplementation 'junit:junit:4.12'
    testImplementation "org.mockito:mockito-core:1.+"

在这个臃肿的文件中很难找到或更新依赖项,而且随着开发的进行,这个文件会变得更糟。

修复混乱

1. 幼稚的方法

我们可以通过为使用的依赖版本创建单独的变量来清理混乱。

    def lifecycle_version = "2.0.0"
    def room_version = "2.1.0-rc01"
    def anko_version = "0.10.4"
    def room_version = "2.1.0-rc01"
    def material_design_version = "1.0.0-rc01"
    def cardview_version = "1.0.0"

    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"

    //Room
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"

    //Design
    implementation "com.google.android.material:material:$material_design_version"

    //CardView
    implementation "androidx.cardview:cardview:$cardview_version"

    //Anko
    implementation "org.jetbrains.anko:anko-commons:$anko_version"

这比以前好,但是当添加新的依赖项时文件仍然会变得混乱,仍有改进的空间。

2. 更好的方法

我们可以创建一个单独的文件来存储我们的依赖项并将其命名为deps.gradle

ext {
    def supportVersion = "27.1.1"
    supportDependencies = [
        design          : "com.android.support:design:$supportVersion",
        cardview        : "com.android.support:cardview-v7:$supportVersion",
        recyclerview    : "com.android.support:recyclerview-v7:$supportVersion"

   ]
}

现在将它导入到build.gradle

dependencies {
    implementation supportDependencies.design
    implementation supportDependencies.cardview
    implementation supportDependencies.recyclerview
}

或者我们也可以单行

dependencies {
    implementation supportDependencies.value()
}

3. 推荐方法

这种方法最适合具有多个模块的项目。

首先,我们必须在根项目中创建一个名为buildSrc的目录并添加Dependencies.ktVersion.kt,这些文件将包含有关我们项目中所有依赖项的信息,目录结构应如下所示

<project>
├── buildSrc
│   └── src
│        └── main
│              └── java
│                    └── Dependencies.kt
│                    └── Version.kt

现在顾名思义,我们将使用Dependencies.kt来存储所有依赖项,并使用Version.kt来存储版本。

我们让我们从内部看一下我们的文件会是什么样子。

//Version.kt will hold all the versions like this
object Version {
    // android configuration
    const val buildTools = "29.0.3"
    const val compileSdk = 29
    const val minSdk = 23
    const val targetSdk = 29
    const val versionCode = 1
    const val versionName = "1.0"

    //Libraries
    const val supportLib = "28.0.0"
    const val recyclerView = "1.0.0"
    const val androidx = "1.0.0"
    const val materialDesign = "1.0.0-rc01"
    const val mockito = "1.10.19"
    const val dagger2 = "2.21"
    const val room = "2.0.0-rc01"
}

//Dependencies.kt will hold all libraries like this
object Dependencies {

    //path to common dependencies (disscussed later)
    private const val path = "../commonFiles/gradleScript/"
    const val common = "${path}common.gradle"

    //path to local dependencies (disscussed later)
    const val dependency = "./gradleScript/dependencies.gradle"

    object Module {
        //Add your modules here
        const val data = ":data"
        const val cache = ":cache"
        const val remote = ":remote"
    }

    //Create object for every libraries being used to group all related dependencies together
    object Chucker {
        const val debug = "com.github.ChuckerTeam.Chucker:library:${Version.chucker}"
        const val release = "com.github.ChuckerTeam.Chucker:library-no-op:${Version.chucker}"
    }

    object Facebook {
        const val stetho = "com.facebook.stetho:stetho:${Version.stetho}"
        const val stethoNetwork = "com.facebook.stetho:stetho-okhttp3:${Version.stetho}"
    }

    object NavigationComponent {
        const val fragment = "androidx.navigation:navigation-fragment-ktx:${Version.navigation}"
        const val ui = "androidx.navigation:navigation-ui-ktx:${Version.navigation}"
    }
}

我们完成了Dependencies.ktVersion.kt

现在,在我们的根项目下再次创建一个目录来存储我们的常用依赖项,我们将其命名为 commonFiles,并在 gradleScript中创建common.gradle

<project>
├── commonFiles
│   └── gradleScript
│        └── common.gradle

在您将要使用的每个模块中创建一个目录gradleScript ,该目录将存储与该模块相关的所有依赖项,并在其中添加文件 dependencies.gradle。

<module>
│   └── gradleScript
│        └── dependencies.gradle

让我们使用我们常见的依赖项,它应该看起来像这样。

//common.gradle
import dependencies.Dependencies

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation Dependencies.Kotlin.kotlin_stdlib_jdk7

    testImplementation Dependencies.Test.test_junit
    testImplementation Dependencies.Test.roboElectric
    testImplementation Dependencies.Test.android_test_room
    testImplementation Dependencies.Test.mockito
}

所以我们只是简单地从我们之前创建的 Dependencies 对象中访问我们的依赖项。同样,在我们的本地依赖项中,我们可以做

//dependencies.gradle
import dependencies.Dependencies

// applying common deps into local deps
apply from: Dependencies.common

dependencies {
    //App Module ( App Module ONLY TO BE INCLUDED IN MAIN APP MODULE)
    implementation project(Dependencies.Module.domain)
    implementation project(Dependencies.Module.cache)
    implementation project(Dependencies.Module.presentaion)

    //RxJava
    implementation Dependencies.RxJava.rxAndroid
    implementation Dependencies.RxJava.rxjava2
    implementation Dependencies.RxJava.rxBinding

    //Dagger2
    implementation Dependencies.Dagger.dagger2
    implementation Dependencies.Dagger.daggerAndroid
    implementation Dependencies.Dagger.daggerAndroidSupport
    kapt Dependencies.Dagger.processor
    kapt Dependencies.Dagger.compiler

}

现在在每个模块级别 build.gradle 的最后一步,我们必须导入dependencies.gradle,它应该看起来像这样

//build.gradle (local)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: "kotlin-kapt"

//this will apply all the local deps stored in local dependencies.gradle
apply from: Dependencies.dependency

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.test.project"
        minSdkVersion Version.minSdk
        targetSdkVersion Version.targetSdk
        versionCode Version.versionCode
        versionName Version.versionName
    }
    ...
}

就是这样,我们制作了易于销售的大型项目且易于管理的工作流程

简单、干净、强大不是吗!!!

只需稍加努力,我们就使我们的代码更具可读性和可管理性。

链接:https://dev.to/ashkay/best-way-to-organise-your-android-dependencies-4f5n

上一篇下一篇

猜你喜欢

热点阅读