安卓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

相关推荐
_祝你今天愉快1 小时前
Java-JVM探析
android·java·jvm
飞天卡兹克1 小时前
forceStop流程会把对应进程的pendingIntent给cancel掉
android
Monkey-旭9 小时前
Android Bitmap 完全指南:从基础到高级优化
android·java·人工智能·计算机视觉·kotlin·位图·bitmap
Mike_Wuzy14 小时前
【Android】发展历程
android
阿华的代码王国15 小时前
【Android】PopupWindow实现长按菜单
android·xml·java·前端·后端
稻草人不怕疼16 小时前
Android 15 全屏模式适配:A15TopView 自定义组件分享
android
静默的小猫17 小时前
LiveDataBus消息事件总线之二-(不含反射和hook)
android
~央千澈~18 小时前
05百融云策略引擎项目交付-laravel实战完整交付定义常量分文件配置-独立建立lib类处理-成功导出pdf-优雅草卓伊凡
android·laravel·软件开发·金融策略
_一条咸鱼_18 小时前
Android Runtime冷启动与热启动差异源码级分析(99)
android·面试·android jetpack