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中配置
Module目录.png

2. Android项目构建

2.1 Android项目构建流程(从源代码到apk文件的打包流程)

说明:Android项目构建流程一句话总结为:java文件经过编译生成.calss字节码文件,之后经过打包生成android可执行的classes.dex文件,然后和资源文件合并为未签名包,最后经过签名生成完整的包。
备注:一个Android Project经过编译打包后生成apk文件,然后再经过签名,就可以安装到设备上。

打包简略流程.png

打包详细流程.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特有的属性配置,必须配置compileSdkVersionbuildToolsVersion
    • compileSdkVersion:用来编译应用的android的API版本号
    • buildToolsVersion:构建和编译所使用的版本号
    • defaultConfig便签:配置应用的核心属性,可覆盖manifest.xml中配置的属性
      • minSdkVersion 16:程序 安装时,允许运行的最小的android的API版本,小于此版本则不允许安装。(一般没必要设置maxSdkVersion)
      • targetSdkVersion 28:程序运行时,若targetSdkVersion与目标设备的API版本相同,则会告诉Android平台此程序在此版本已经经过充分测试,不必为此程序开启兼容性检查判断的工作了,因此运行效率可能会高一些,从而提高指定版本的设备上程序运行体验。
  • 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不用被反编译,获取就算被反编译代码也不易看懂,无法知道代码的真正作用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容