安卓Gradle总结

1. 简介

Gradle 是 Android 官方推荐的构建系统,基于 Groovy DSL,通过脚本化的方式管理项目依赖、任务执行和打包流程

一套标准的安卓项目应该如下:

bash 复制代码
projectRoot/
├── app/            # 主模块(可自定义命名)
│   ├── src/        # 源代码目录(按包名分类)
│   │   ├── main/      # Java/Kotlin + 资源文件(布局/图片/字符串等)
│   │   └── androidTest/ # 设备端测试代码
│   ├── build.gradle     # 模块级构建脚本(定义依赖、插件等)
├── build.gradle       # 顶层全局设置(如仓库地址、公共依赖)
└── settings.gradle    # 指定参与构建的模块列表

gradle编译的过程如下:

1). 解析settings.gradle

该文件是项目级别的gradle文件,用于确定参与构建的所有模块,加载环境变量和属性文件。

2). 配置阶段

执行各模块的 build.gradle,创建任务图并建立依赖关系模型。此时不会实际执行任何操作

3). 执行阶段

合并资源 → 编译Java→处理Manifest→打包APK→签名对齐

2. settings.gradle配置

settings.gradle最基础的作用是指定哪些目录被视为项目的子模块,如:

bash 复制代码
include("app", "library", "another-module") 

如果省略此句,默认只会将当前根目录作为唯一项目;对于多模块工程必须显式声明。

还可以设置跨项目的属性传递,向所有子项目暴露通用的配置参数

bash 复制代码
rootProject {
    extensions.add("myGlobalProp", "value") // 自定义扩展属性
}

然后在任意子模块的build.gradle中可以直接读取参数:

bash 复制代码
println project.property('myGlobalProp')  // => "value"

再一个就是配置插件的来源,增强安全性:

bash 复制代码
pluginManagement {
    repositories {
        maven { url = uri(" ") } //可以写一些镜像源
        gradlePluginPortal() // 官方仓库仍建议保留
    }
}

3. build.gradle配置

build.gradle在根目录下会有一个,是用于顶层全局配置,比如设置仓库地址,公共依赖等。每个模块下,还会有一个模块级的build.gradle,会牵扯到模块的业务逻辑,用于构建模块。

顶层build.gradle一般会配置如下:

bash 复制代码
//插件门户管理
pluginManagement {
    repositories {
        mavenCentral() // 确保能下载到最新插件版本
        google()       // Android官方插件源
        gradlePluginPortal() // Gradle社区认证的插件仓库
    }
}
//集中定义所有Maven/Ivy源以避免重复代码
allprojects {
    repositories {
        maven { url = uri("https://maven.aliyun.com/repository/public") } // 阿里云镜像加速国内访问
        mavenLocal() // 优先使用本地缓存的构件
        mavenCentral() // JCenter已废弃,改用中央库替代方案
    }
}

项目级build.gradle:

  • 域声明:必须以 apply plugin: 'com.android.application' 开头(应用)或 library(库),启用对应类型的编译逻辑。
  • 配置块:关键属性包括:
    defaultConfig { ... } → 设置默认维度(如版本号、屏幕密度适配策略);
    dependencies { ... } → 引入三方库(如 implementation 'com.squareup.retrofit2:retrofit:2.9.0');
    android { ... } → 精细调控编译选项(混淆规则、NDK支持等)
  • 变量复用:利用 ext 或 extra 集中管理常量值,提升可维护性。
bash 复制代码
plugins {
    id 'com.android.application'
}

android {
    ...
    defaultConfig {
        applicationId "com.example.myapp"
        minSdkVersion 21     //minSdk targetSdk 这些类写法都已经弃用
        targetSdkVersion 30
        versionCode 1
        versionName "1.0.0"  // 修改此处的值即可改变APK的名称
        ...
    }

	// 所有flavor相关资源都应该配置在模块级的src/目录下,用于表示不同版本的代码
    productFlavors{
        free{
            resValue "string", "app_name", "free"
        }
        paid{
        	resValue "string", "app_name", "paid"
		}
    }
   
	//指定签名
    signingConfigs {
    // debug 和 release 分开写
        debug {
            storeFile file("${project.rootDir}/mykey.keystore")
            storePassword '123456'
            keyAlias 'mykey'
            keyPassword '123456'
        }
    }
    
	关于文件路径最好使用动态路径,灵活性更高不易冲突
    buildTypes {
        debug {
            buildConfigField "boolean", "ENABLE_LOGGING", "true"
            resValue "string", "app_name", "MyApp"
            //自定义输出目录   
            // 将debug构建的APK输出到模块的根目录下的debug目录
            outputFile = "${rootProject.projectDir}/outputs/debug/app-debug.apk"
        }
        release {
            buildConfigField "boolean", "ENABLE_LOGGING", "true"
            resValue "string", "app_name", "MyApp"  //用于替代AndroidMainfest.xml中的字段
            // 将release构建的APK输出到模块的根目录下的release目录
            outputFile = "${rootProject.projectDir}/outputs/release/app-release.apk"
        }
    }

	// 编译版本 显示指定编译的JDK版本  1_8对应java8 11 17 21 分别对应java11 java17 java21 
	// 这里注意 通过android studio里面 project structure Gradles setting 里面的jdk设置也可以设定编译环境的版本,但是如果在下面显示声明,将会覆盖设置,targetCompatibility 设定的版本具有最高优先级
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

	// 依赖库添加 包括本地和远程依赖
	dependencies {
	}

4. 实用工具

编译出问题的时候可以通过以下命令获取详细错误信息:

bash 复制代码
./gradlew assembleDebug --stacktrace --info

./gradlew lint //用于代码检查,可以排除一些代码规范问题

5. 性能优化方面

这方面内容参考于其他人的博客,(传送门) ,有些配置我还没有实际试过,不知道效果如何,先整理出来,有时间尝试一下。

5.1 未使用资源

未使用的资源是那些在应用程序中从未被引用和加载的文件,它们在APK包中仅增加了不必要的体积。随着应用程序的增长,这些文件的数量和体积也可能随之增加,导致最终的APK文件大小超出必要的范围。更大的APK文件意味着更高的存储空间要求,对于存储空间有限的用户来说,这是一个不小的负担。此外,更大的APK文件在下载和安装时会消耗用户的更多流量和时间,影响用户体验。

除了存储和安装时的问题,未使用的资源还会对应用程序的运行性能产生影响。首先,它们增加了应用的加载时间,因为系统需要处理更多的文件;其次,在应用程序运行时,系统可能会浪费资源去管理和维护这些未使用的文件,从而降低了应用程序的性能和响应速度。在对资源敏感的移动平台上,这种性能的下降尤为明显。

5.2 使用shrinkResources属性

在 build.gradle 文件中,我们可以启用资源收缩(shrinking)功能来自动删除未使用的资源。这可以通过设置 buildTypes 中的 shrinkResources 属性为 true 来完成。启用此属性后,构建过程将分析APK以找出并移除未使用的资源。

bash 复制代码
android {
    buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

当 minifyEnabled 设置为 true 时,Gradle会使用ProGuard或R8(Android的默认混淆器,从Android Gradle Plugin 3.4.0开始)来压缩代码和资源。这不仅能移除未使用的资源,还能对代码进行混淆,增加逆向工程的难度,从而提升应用的安全性。

在配置 minifyEnabled 时,我们还需要指定一个或多个混淆规则文件,这些文件定义了哪些代码可以被移除,哪些代码应该被保留。混淆规则文件通常是 proguard-android.txt (由Android SDK提供)和项目特定的规则文件 proguard-rules.pro

5.3 代码混淆原理和重要性

代码混淆是一种代码保护技术,它的目的是通过各种手段使得应用程序的代码难以被理解,从而防止恶意用户逆向分析代码,达到保护应用程序的目的。在Android开发中,混淆通常通过ProGuard或R8这样的工具来实现。

混淆的主要原理是通过删除、重命名、以及复杂化的方法和类名来隐藏应用的真正逻辑。这样即使被反编译,攻击者也很难从代码中获得有价值的信息。

代码混淆的重要性不言而喻,尤其对于发布在公共平台的应用来说,能够有效地防止反编译,保护商业机密和用户数据。混淆还可以减少代码大小,通过缩短标识符的名称来减小最终的APK体积。

proguard-rules.pro 文件中,可以自定义各种混淆规则

bash 复制代码
// proguard-rules.pro
# Keep class names
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

# Keep our Log class methods
-keep class com.example.myapp.utils.Log {
    public static <methods>;
}

# If we use GSON
-keepattributes Signature
-keepattributes EnclosingMethod

混淆过程中,除了使用默认的混淆规则外,根据应用的需要,可能还需要保留某些类、方法和属性不被混淆,例如,使用 @JavascriptInterface 注解的方法以及一些日志类方法。

参考连接:https://blog.csdn.net/weixin_42613360/article/details/149615208

相关推荐
maki07721 小时前
虚幻版Pico大空间VR入门教程 05 —— 原点坐标和项目优化技巧整理
android·游戏引擎·vr·虚幻·pico·htc vive·大空间
千里马学框架1 天前
音频焦点学习之AudioFocusRequest.Builder类剖析
android·面试·智能手机·车载系统·音视频·安卓framework开发·audio
fundroid1 天前
掌握 Compose 性能优化三步法
android·android jetpack
TeleostNaCl1 天前
如何在 IDEA 中使用 Proguard 自动混淆 Gradle 编译的Java 项目
android·java·经验分享·kotlin·gradle·intellij-idea
旷野说1 天前
Android Studio Narwhal 3 特性
android·ide·android studio
maki0771 天前
VR大空间资料 01 —— 常用VR框架对比
android·ue5·游戏引擎·vr·虚幻·pico
xhBruce2 天前
InputReader与InputDispatcher关系 - android-15.0.0_r23
android·ims
领创工作室2 天前
安卓设备分区作用详解-测试机红米K40
android·java·linux
hello_ludy2 天前
Android 中的 mk 和 bp 文件编译说明
android·编译
maki0772 天前
VR大空间资料 03 —— VRGK使用体验和源码分析
android·vr·虚幻·源码分析·oculus·htc vive·vrgk