1. Android Studio項目目錄
(1) 區(qū)別Project和Module
- Module(模塊):編寫android獨立模塊的業(yè)務(wù)代碼,即android的
組件化開發(fā)
,可復(fù)用
的組件化思想让蕾。 - Project(工程):一個Project可以
包含
多個Module脸狸。
Project和Module關(guān)系.png
(2) 項目結(jié)構(gòu)
說明:項目結(jié)構(gòu)大體上分為編譯系統(tǒng)gradle
亡呵、配置文件
和應(yīng)用模塊Module
馋辈。具體項目文件如下
- .gradle:gradle編譯的腳本
- .idea:AndroidStudio所需要的文件
- build:Project或Module編譯之后所生成的文件(如:apk和臨時文件)
- gradle:gradle的wrapper文件是對gradle的封裝覆获,更新以前舊版本的gradle
- .gitignore:git相關(guān)墩新,配置git上傳時的忽略文件
- build.gradle:配置文件
- gradle.properties:全局配置文件贸弥,作用在所有的Module
- gradlew:Linux下的gradle可執(zhí)行文件
- gradlew.bat:Windows下的gradle可執(zhí)行文件
- local.properties:本地屬性設(shè)置(git上傳時不推薦上傳到本地倉庫的文件)
- settings.gradle:配置和設(shè)置相關(guān)的gradle腳本
- Module下的文件
- build:Module編譯之后所生成的文件
- libs:第三方的jar和aar文件
- src:開發(fā)的業(yè)務(wù)代碼(java文件和布局等)
- .gitignore:git忽略文件
- build.gradle:與模塊相關(guān)的gradle配置
- .iml:
- proguard-rules.pro:代碼混淆配置文件(有利于app的保護和體積縮小),混淆配置是否開啟需在build.gradle中配置
2. Android項目構(gòu)建
2.1 Android項目構(gòu)建流程(從源代碼到apk文件的打包流程)
說明:Android項目構(gòu)建流程一句話總結(jié)為:java文件經(jīng)過
編譯
生成.calss字節(jié)碼文件海渊,之后經(jīng)過打包
生成android可執(zhí)行的classes.dex文件,然后和資源文件合并
為未簽名包绵疲,最后經(jīng)過簽名
生成完整的包。
備注:一個Android Project經(jīng)過編譯
和打包
后生成apk文件臣疑,然后再經(jīng)過簽名
盔憨,就可以安裝到設(shè)備上。
(1) 通過
aapt
打包res資源文件讯沈,生成R.java和resources.arsc(2) 處理
.aidl
文件郁岩,生成對應(yīng)的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 持續(xù)集成構(gòu)建
3. Git版本控制
(1) 區(qū)別工作區(qū)和gitignore
- 工作區(qū):可見的文件目錄即為工作區(qū)(如一個Progect就是一個工作區(qū))
- gitignore文件:配置忽略文件(不想進行版本控制的文件)
(2) 常用git命令
備注:可通過git --help查看所有的git命令笼恰。
- git init:創(chuàng)建git倉庫 (運行之后項目中會多一個.git的隱藏目錄踊沸,里面放置git的版本庫內(nèi)容)
- git status:查看當前倉庫的狀態(tài)
- git diff + filename:對比文件改動
- git add + filename:更改的文件添加到暫存區(qū)
- git commit:將暫存區(qū)文件提交到遠程倉庫代碼分支上(git倉庫創(chuàng)建時會自動創(chuàng)建一個master分支,不指定分支挖腰,默認提交到master分支,可通過checkout命令切換分支來開發(fā))
- git clone + giturl:從遠程倉庫克隆代碼到本地
- git branch:查找當前分支
- git checkout + newbranch:切換分支练湿,在新分支上(如:develop分支)開發(fā)
(3)2種主流的git工作流
- fork/clone流程(綠線標識):將遠程項目代碼以foke形式保存到自己的遠程倉庫猴仑,之后將自已遠程倉庫的代碼克隆到本地,在本地修改代碼后提交到自己的暫存區(qū)上肥哎,然后將本地的代碼以push形式提交到自己的遠程倉庫辽俗,最后以pull request的形式將代碼發(fā)送給遠程倉庫管理人讓他來合并代碼。
-
clone流程(紅線標識):傳統(tǒng)的clone流程篡诽,跳過了自己的遠程倉庫崖飘,直接從項目遠程倉庫克隆一份代碼到本地,本地改動后又直接push到遠程倉庫杈女。
2種主流的git工作流.png
說明:clone流程缺少了代碼管理人朱浴, fork/clone流程有代碼管理人,保證了代碼質(zhì)量达椰,大型項目大多采用 fork/clone來保證代碼的質(zhì)量翰蠢。
4. Gradle
說明:新創(chuàng)建項目時會同時生成3個gradle文件。
(1) Project下的settings.gradle:多模塊開發(fā)時使用啰劲,配置各個模塊的屬性
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插件:谷歌官方提供的用于構(gòu)建廷支、測試和打包android項目的插件,android屬性和dependencies屬性都依賴于該插件栓辜。
- android標簽代碼塊:android特有的屬性配置恋拍,必須配置
compileSdkVersion
和buildToolsVersion
。- compileSdkVersion:用來
編譯
應(yīng)用的android的API版本號 - buildToolsVersion:
構(gòu)建
和編譯所使用的版本號 - defaultConfig便簽:配置應(yīng)用的核心屬性藕甩,可
覆蓋manifest.xml
中配置的屬性- minSdkVersion 16:程序
安裝
時芝囤,允許運行的最小的android的API版本,小于此版本則不允許安裝。(一般沒必要設(shè)置maxSdkVersion) - targetSdkVersion 28:程序
運行
時悯姊,若targetSdkVersion與目標設(shè)備的API版本相同羡藐,則會告訴Android平臺此程序在此版本已經(jīng)經(jīng)過充分測試,不必為此程序開啟兼容性檢查判斷的工作了悯许,因此運行效率可能會高一些仆嗦,從而提高指定版本的設(shè)備上程序運行體驗。
- minSdkVersion 16:程序
- compileSdkVersion:用來
- dependencies標簽代碼塊:模塊所依賴的第三方開源庫先壕。(如:okhttp瘩扼、retrofit、volley垃僚、glide和butterknife等)
5. ProGuard代碼混淆技術(shù)
(1) ProGuard及功能:ProGuard技術(shù)用于angroid打包時壓縮
集绰、優(yōu)化
及混淆
我們的代碼。
- 壓縮(Shrink):檢查并移除無用的類谆棺、字段栽燕、屬性和方法,減小apk打包的體積
- 優(yōu)化(Optimize):移除.class字節(jié)碼文件中的無用指令
- 混淆Obfuscate):將開發(fā)中有意義的名詞變成無意義的名詞改淑,使apk不易被反編譯或者就算被反編譯也無法知道代碼的作用碍岔,有利于金融類及購物類等的app的安全性
- 預(yù)檢測(Preveirfy):在Java平臺上對處理后的代碼進行預(yù)檢,確保加載的.class文件是可執(zhí)行的
說明:ProGuard已經(jīng)集成到android的構(gòu)建系統(tǒng)中朵夏,所以在開發(fā)中不需要手動去調(diào)用它蔼啦,但我們要了解它的原理。只有構(gòu)建應(yīng)用并發(fā)布到應(yīng)用市場時才會使用ProGuard技術(shù)仰猖,在debudge時不需要進行代碼混淆捏肢,即:在debug模式下不會開啟ProGuard,而在release模式下會自動開啟ProGuard代碼混淆技術(shù)饥侵。ProGuard是一種可選的技術(shù)猛计,不使用也能運行我們的代碼,但是最好使用爆捞,它能影響應(yīng)用的體積和安全性奉瘤。
buildTypes {
release {
minifyEnabled true //開啟混淆
zipAlignEnabled true //壓縮優(yōu)化
shrinkResources true //移出無用資源
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //默認的混淆文件以及我們指定的混淆文件
}
}
備注:開啟了混淆還需在proguard-rules.pro文件編輯混淆規(guī)則,混淆規(guī)則網(wǎng)上也有很多煮甥,自行百度即可盗温。
(2) ProGuard工作原理
EntryPoint類:標識不會被處理的類和方法
非EntryPoint類:對非EntryPoint類進行混淆重命名
(3) 為什么要使用ProGuard
java是一種跨平臺的解釋性語言,java的源碼會被編譯成.class字節(jié)碼文件成肘;由于跨平臺的需要卖局,字節(jié)碼文件中包含了很多java源碼的信息(如:變量名和方法名,可通過變量名和方法名來訪問變量和方法)双霍,這個信息對程序運行無用但卻容易被反編譯砚偶。所以需要ProGuard代碼混淆技術(shù)來移除并混淆.class字節(jié)碼文件批销,即對將要發(fā)布的應(yīng)用進行處理,使處理后的代碼和處理前的代碼不同染坯,但卻能實現(xiàn)相同的功能均芽。因此時apk不用被反編譯,獲取就算被反編譯代碼也不易看懂单鹿,無法知道代碼的真正作用掀宋。