Android项目构建
1. Android Studio项目目录
(1) 区别Project和Module
- Module(模块):编写android独立模块的业务代码,即android的
组件化开发
,可复用
的组件化思想。 - Project(工程):一个Project可以
包含
多个Module。
Project和Module关系.png
(2) 项目结构
说明:项目结构大体上分为编译系统gradle
、配置文件
和应用模块Module
。具体项目文件如下
- .gradle:gradle编译的脚本
- .idea:AndroidStudio所需要的文件
- build:Project或Module编译之后所生成的文件(如:apk和临时文件)
- gradle:gradle的wrapper文件是对gradle的封装,更新以前旧版本的gradle
- .gitignore:git相关,配置git上传时的忽略文件
- build.gradle:配置文件
- gradle.properties:全局配置文件,作用在所有的Module
- gradlew:Linux下的gradle可执行文件
- gradlew.bat:Windows下的gradle可执行文件
- local.properties:本地属性设置(git上传时不推荐上传到本地仓库的文件)
- settings.gradle:配置和设置相关的gradle脚本
- Module下的文件
- build:Module编译之后所生成的文件
- libs:第三方的jar和aar文件
- src:开发的业务代码(java文件和布局等)
- .gitignore:git忽略文件
- build.gradle:与模块相关的gradle配置
- .iml:
- proguard-rules.pro:代码混淆配置文件(有利于app的保护和体积缩小),混淆配置是否开启需在build.gradle中配置
2. Android项目构建
2.1 Android项目构建流程(从源代码到apk文件的打包流程)
打包简略流程.png说明:Android项目构建流程一句话总结为:java文件经过
编译
生成.calss字节码文件,之后经过打包
生成android可执行的classes.dex文件,然后和资源文件合并
为未签名包,最后经过签名
生成完整的包。
备注:一个Android Project经过编译
和打包
后生成apk文件,然后再经过签名
,就可以安装到设备上。
打包详细流程.png
(1) 通过
aapt
打包res资源文件,生成R.java和resources.arsc(2) 处理
.aidl
文件,生成对应的Java接口文件(3) 通过
Java Compiler
编译R.java、Java接口文件、Java源文件,生成.class文件(4) 通过
dex命令
,将.class文件和第三方库中的.class文件处理生成classes.dex(5) 通过
apkbuilder工具
,将classes.dex和aapt生成的resources.arsc一起打包生成apk(6) 通过
Jarsigner工具
,对上面的apk进行debug或release签名(7) 通过
zipalign工具
,将签名后的apk进行对齐处理。
2.2 jenkins 持续集成构建
3. Git版本控制
(1) 区别工作区和gitignore
- 工作区:可见的文件目录即为工作区(如一个Progect就是一个工作区)
- gitignore文件:配置忽略文件(不想进行版本控制的文件)
(2) 常用git命令
备注:可通过git --help查看所有的git命令。
- git init:创建git仓库 (运行之后项目中会多一个.git的隐藏目录,里面放置git的版本库内容)
- git status:查看当前仓库的状态
- git diff + filename:对比文件改动
- git add + filename:更改的文件添加到暂存区
- git commit:将暂存区文件提交到远程仓库代码分支上(git仓库创建时会自动创建一个master分支,不指定分支,默认提交到master分支,可通过checkout命令切换分支来开发)
- git clone + giturl:从远程仓库克隆代码到本地
- git branch:查找当前分支
- git checkout + newbranch:切换分支,在新分支上(如:develop分支)开发
(3)2种主流的git工作流
- fork/clone流程(绿线标识):将远程项目代码以foke形式保存到自己的远程仓库,之后将自已远程仓库的代码克隆到本地,在本地修改代码后提交到自己的暂存区上,然后将本地的代码以push形式提交到自己的远程仓库,最后以pull request的形式将代码发送给远程仓库管理人让他来合并代码。
-
clone流程(红线标识):传统的clone流程,跳过了自己的远程仓库,直接从项目远程仓库克隆一份代码到本地,本地改动后又直接push到远程仓库。
2种主流的git工作流.png
说明:clone流程缺少了代码管理人, fork/clone流程有代码管理人,保证了代码质量,大型项目大多采用 fork/clone来保证代码的质量。
4. Gradle
说明:新创建项目时会同时生成3个gradle文件。
gradle.png
(1) Project下的settings.gradle:多模块开发时使用,配置各个模块的属性
include ':app', ':newmodulle'
(2) Project下的build.gradle:声明项目自身需要的资源,如依赖项、第三方插件和仓库地址等信息
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
(3) Module下的build.gradle:每个Module独有的配置文件,可覆盖Project下的build.gradle的配置
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion '28.0.2'
defaultConfig {
applicationId "comi.example.liy.mytestdemo"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.jetbrains:annotations-java5:15.0'
}
- android插件:谷歌官方提供的用于构建、测试和打包android项目的插件,android属性和dependencies属性都依赖于该插件。
- android标签代码块:android特有的属性配置,必须配置
compileSdkVersion
和buildToolsVersion
。- compileSdkVersion:用来
编译
应用的android的API版本号 - buildToolsVersion:
构建
和编译所使用的版本号 - defaultConfig便签:配置应用的核心属性,可
覆盖manifest.xml
中配置的属性- minSdkVersion 16:程序
安装
时,允许运行的最小的android的API版本,小于此版本则不允许安装。(一般没必要设置maxSdkVersion) - targetSdkVersion 28:程序
运行
时,若targetSdkVersion与目标设备的API版本相同,则会告诉Android平台此程序在此版本已经经过充分测试,不必为此程序开启兼容性检查判断的工作了,因此运行效率可能会高一些,从而提高指定版本的设备上程序运行体验。
- minSdkVersion 16:程序
- compileSdkVersion:用来
- dependencies标签代码块:模块所依赖的第三方开源库。(如:okhttp、retrofit、volley、glide和butterknife等)
5. ProGuard代码混淆技术
(1) ProGuard及功能:ProGuard技术用于angroid打包时压缩
、优化
及混淆
我们的代码。
- 压缩(Shrink):检查并移除无用的类、字段、属性和方法,减小apk打包的体积
- 优化(Optimize):移除.class字节码文件中的无用指令
- 混淆Obfuscate):将开发中有意义的名词变成无意义的名词,使apk不易被反编译或者就算被反编译也无法知道代码的作用,有利于金融类及购物类等的app的安全性
- 预检测(Preveirfy):在Java平台上对处理后的代码进行预检,确保加载的.class文件是可执行的
说明:ProGuard已经集成到android的构建系统中,所以在开发中不需要手动去调用它,但我们要了解它的原理。只有构建应用并发布到应用市场时才会使用ProGuard技术,在debudge时不需要进行代码混淆,即:在debug模式下不会开启ProGuard,而在release模式下会自动开启ProGuard代码混淆技术。ProGuard是一种可选的技术,不使用也能运行我们的代码,但是最好使用,它能影响应用的体积和安全性。
buildTypes {
release {
minifyEnabled true //开启混淆
zipAlignEnabled true //压缩优化
shrinkResources true //移出无用资源
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //默认的混淆文件以及我们指定的混淆文件
}
}
备注:开启了混淆还需在proguard-rules.pro文件编辑混淆规则,混淆规则网上也有很多,自行百度即可。
(2) ProGuard工作原理
EntryPoint类:标识不会被处理的类和方法
非EntryPoint类:对非EntryPoint类进行混淆重命名
(3) 为什么要使用ProGuard
java是一种跨平台的解释性语言,java的源码会被编译成.class字节码文件;由于跨平台的需要,字节码文件中包含了很多java源码的信息(如:变量名和方法名,可通过变量名和方法名来访问变量和方法),这个信息对程序运行无用但却容易被反编译。所以需要ProGuard代码混淆技术来移除并混淆.class字节码文件,即对将要发布的应用进行处理,使处理后的代码和处理前的代码不同,但却能实现相同的功能。因此时apk不用被反编译,获取就算被反编译代码也不易看懂,无法知道代码的真正作用。