SlideShare a Scribd company logo
不只自動化而且更敏捷的Android開發工具
Gradle
邱炫儒
CI engineer @ HTC
“PROJECT CODE RUSH”
Usage Attribution-Noncommercial-Share Alike 3.0 United Stateshttps://archive.org/details/CodeRush
十五年前的持續整合
How people do CI 15 years ago
解決問題的方法是...
Automate everything
and smoothly
可重複運行 可重製錯誤 減少人為/環境錯誤 流程透明 產生更有品質的程式碼
Coding Check-in Build Test Publish
Gradle - offering thoughtful conventions
Gradle build files are groovy scripts
From Command line to IDE to CI
Product Flavor
Powerful dependencies management
消除溝通的嫌隙
Convention 1
一句話惹毛DevOps:
我電腦沒這個問題呀!
溝通的嫌隙
module B
developer
build server
module A
developer
ant
ALPHA
proguard
shrink
resources
android
gradle plugin
BETA RC
SDK build.xmlADT
eclipse
gradle
debug on/off
Production
Schedule
SCM
commercial
configuration
APKs
module
A
module
B all
modules
1
2
3
phone tablet
減少溝通的嫌隙
From command line to IDE to continuous integration
module B
developer
build server
module A
developer
ALPHA
proguard
shrink
resources
android
gradle plugin
BETA RC
gradle
debug on/off
Production
Schedule
SCM
commercial
configuration
APKs
all
modules
3
phone tablet
後期出現的錯誤往往影響巨大
將商業版本客製盡量提前到開發時期
Product Flavor and Multiple APK
Convention 2
<manifest ... >
<supports-screens android:smallScreens="false"
android:normalScreens="false"
android:largeScreens="true"
android:xlargeScreens="true"
android:requiresSmallestWidthDp="600"
/>
...
</manifest>
custom AndroidManifest.xml for tablet
Example on Google dev site:
Design Multi-APK for tablet and phone
Google Play
The versionName/versionCode schema for multiple APK
versionCode (04 01 310)
phone screen
App version(3.1.0)API Level(4+)
versionCode (04 02 310)
tablet screen
App version(3.1.0)API Level(4+)
release 1
versionCode (04 01 311)
phone screen
App version(3.1.1)API Level(4+)
versionCode (04 02 311)
tablet screen
App version(3.1.1)API Level(4+)
release 2
upload
APKs
upload
APKs
Version Name:
3.1.0-build1
Version Name:
3.1.1-build2
把處理邏輯都編寫至gradle設定檔中
android{
defaultConfig {
versionName computeVersionName()
}
productFlavors {
phone{ versionCode computeVersionCode(1) }
tablet { versionCode computeVersionCode(2) }
}
}
def computeVersionCode(int flavor) {
def version_code = ext.minSdkVersion * 100000 + flavor * 1000 + ext.versionMajor * 100 + ext.versionMinor*10 
+ ext.versionIncremental
return version_code
}
def computeVersionName(){
def buildNumber = System.getenv("BUILD_NUMBER") ?: "dev"
def version_name = ext.versionMajor+"."+ext.versionMinor+”.”+ext.versionIncremental+"-"+buildNumber
return version_name
}
custom build logic and integrate with Jenkins
build.gradle:
為什麼要把Jenkins buildNumber 寫進
version name?
為什麼要把Jenkins buildNumber 寫進
version name?
混在一起做撒尿牛丸?
為什麼要把Jenkins buildNumber 寫進
version name?
混在一起做Dogfooding
What is Dogfooding?
Dogfooding等於良好的版本管控策略
Library
Source
Project
Source
alpha 1 beta1Debug APK
Release 2Release APK
beta2
Release 1
alpha 1 beta2
OTA
Issue Tracking bug report
Release 2
OTAPRELOAD
Employee Device
透過Jenkins追朔程式碼
versionName
3.1.0-Build#2
程式碼和腳本Script 都寫好了
哪些東西要放上SCM?
有條不紊的程式碼管理
Convention 3
“By distributing your project source based on
gradle ,anyone can work with it without needing to
install many annoying tools/dependencies
beforehand”
“Users of the build are guaranteed to use the same
process and the same dependencies version that
was designed to work with”
from http://gradle.org/
答案很明顯了
全部都放上SCM?
SCM (git)
Keep your workspace clean
建立可重複且可靠的流程
SCM (git)
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
Use .gitignore
Build Once Build Anywhere
建立可重複且可靠的流程
Build script as code
gradle wrapper
#Sun Aug 09 19:57:07 CST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-2.5-all.zip
Dependencies Management
Convention 4
root project
lib-proj
widget
lib-proj
Activity
firebase
sdk
facebook
sdk
evernote
sdk
dropbox
sdk
Google play service libgoogle
support v4
log/util
module
drive
Google+
games
analytic
s
Location
Ads
maps
nearby
wallet
google
support
appcompat-v7
google support
design lib
google support
multidex
google support
multidex instrumentation
A large scale Android App
root project
lib-proj
widget
lib-proj
Activity
firebase
sdk
evernote
sdk
dropbox
sdk
Google play service libgoogle
support v4
log/util
module
drive
Google+
games
analytic
s
Location
Ads
maps
nearby
wallet
google
support
appcompat-v7
google support
design lib
google support
multidex
google support
multidex instrumentation
facebook
sdk
The dependency nightmare
Before Maven
Getting started with the Dropbox Android SDK:
1. Include everything under lib/ in your project/build.
2. You'll want to start off by creating an
AndroidAuthSession with your consumer key and secret.
3...
Download dropbox-android-sdk from dropbox website
1
2
到底用了哪一版library?
┌Top Android Project
│
├── Project 1 - (Pure Java Modules)
│ │
│ ├── Module A1
│ │ └──libs/android-support-v4_22.jar
│ ├── Module B1
│ :
│ └── facebook-lib-project
│ └──libs/android-support-v4-v22.0.0.jar
│
BUILD FAIL
After Maven
dependencies {
compile 'com.facebook.android:facebook-android-sdk:4.1.0'
}
1. Use gradle
2.
3. That’s it.
dependencies {
compile 'com.google.android.gms:play-services-wearable:7.3.0'
}
How about the depend on a tree of dependencies?
dependencies {
compile 'com.facebook.android:facebook-android-sdk:4.1.0'
}
dependencies {
compile 'com.google.android.gms:play-services-wearable:7.3.0'
}
android-support-v4:21.0.0
android-support-v4:22.0.0
Gradle could be even better
Transitive Dependencies on Gradle(可遞移性相依)
A -> B and B -> C
hence A -> C
google play service aar library hierarchy on maven
Tips of transitive dependencies
dependencies {
compile 'com.facebook.android:facebook-android-sdk:4.1.0'
}
dependencies {
compile 'com.google.android.gms:play-services-wearable@aar:7.3.0'
}
android-support-v4:21.0.0
android-support-v4:22.0.0
As a library provider
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.android.gms</groupId>
<artifactId>play-services-location</artifactId>
<version>7.8.0</version>
<packaging>aar</packaging>
<dependencies>
<dependency>
<groupId>com.google.android.gms</groupId>
<artifactId>play-services-maps</artifactId>
<version>7.8.0</version>
<scope>compile</scope>
<type>aar</type>
</dependency>
…...
Maven Repository
pom.xml
remember to provide your transitive
dependencies in pom.xml
Handle dependency conflict
Gradle offers the following conflict resolution strategies:
Newest: The newest version of the dependency is used. This is Gradle's default strategy,
and is often an appropriate choice as long as versions are backwards-compatible.
Fail: A version conflict results in a build failure. This strategy requires all version
conflicts to be resolved explicitly in the build script.
Use ‘Fail’ resolution strategy
configurations.all {
resolutionStrategy {
// fail eagerly on version conflict (includes transitive dependencies)
// e.g. multiple different versions of the same dependency (group and name are equal)
failOnVersionConflict()
}
}
build.gradle:
Handle dependency conflict
dependencies {
compile('org.hibernate:hibernate:3.1') {
//in case of versions conflict '3.1' version of hibernate wins:
force = true
//disabling all transitive dependencies of this dependency
transitive = false
}
}
build.gradle:
dependency substitution
51.8.3.1. Substituting an external module dependency with a project dependency
One use case for dependency substitution is to use a locally developed version of a module in
place of one that is downloaded from an external repository. This could be useful for testing a
local, patched version of a dependency.
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute module("org.utils:api") with project(":api")
substitute module("org.utils:util:2.5") with project(":util")
}
}
build.gradle:
Versioning Control
dependencies {
compile 'com.facebook.android:facebook-android-sdk:4.1.0'
}
dependencies {
compile 'com.facebook.android:facebook-android-sdk:4.1.+'
}
dependencies {
compile 'com.facebook.android:facebook-android-sdk:4.1.0-SNAPSHOT'
}
建置系統始終應該指定專案所需外部類別庫的確切版本:
開發時期指定專案所需外部函式庫的最新版本:
開發時期指定專案所需外部函式庫的SNAPSHOT版本:
若違背架構原則就讓建置失敗(optional)
Reference
 Android plugin for gradle:
https://developer.android.com/tools/building/plugin-for-gradle.html:
 Android tools project site, tips:
http://tools.android.com/tech-docs/new-build-system/tips
 Gradle dependency management:
https://docs.gradle.org/current/userguide/dependency_management.ht
ml
 Google dev site, multiple apk:
https://developer.android.com/google/play/publishing/multiple-
apks.html
 Project Code Rush:
https://archive.org/details/CodeRush
 Sample project on github:
https://github.com/iamsamchiu/AndroidSampleForGradleUsage
Q&A

More Related Content

PDF
不只自動化而且更敏捷的Android開發工具 gradle mopcon
PDF
From devOps to front end Ops, test first
PDF
Automate your build on Android with Jenkins
PDF
DevOps 及 TDD 開發流程哲學
PDF
Trunk-Based Development
PDF
Jfokus 2017 - The DevOps Disaster
PDF
ApacheCon Europe 2016 : CONTAINERS IN ACTION - Transform Application Delivery...
PPTX
SanDiego_DevOps_Meetup_9212016-v8
不只自動化而且更敏捷的Android開發工具 gradle mopcon
From devOps to front end Ops, test first
Automate your build on Android with Jenkins
DevOps 及 TDD 開發流程哲學
Trunk-Based Development
Jfokus 2017 - The DevOps Disaster
ApacheCon Europe 2016 : CONTAINERS IN ACTION - Transform Application Delivery...
SanDiego_DevOps_Meetup_9212016-v8

What's hot (20)

PPTX
Micronaut: A new way to build microservices
PDF
Owasp Juice Shop: Achieving sustainability for open source projects
PPTX
Gradle,the new build system for android
PPTX
Continuous Delivery Applied (AgileDC)
ODP
Unit Test Android Without Going Bald
PPTX
Gradle: One technology to build them all
KEY
Continuous deployment
PDF
OWASP Juice Shop 5.x and beyond
PDF
Running Spring Boot Applications as GraalVM Native Images
PDF
Lean Engineering. Applying Lean Principles to Building Experiences
PDF
"How to deploy to production 10 times a day" Андрей Шумада
PDF
Tips for better CI on Android
PDF
JPQL/ JPA Activity 1
 
PPTX
JIRA & Stach, The Love Story
PDF
Peering Inside the Black Box: A Case for Observability
PDF
Agile Fundamental Skill Set
ODP
Continuous Integration and PHP
PDF
はじめての JFrog Xray
PPTX
Simplified CI/CD Flows for Salesforce via SFDX - Downunder Dreamin - Sydney
PDF
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...
Micronaut: A new way to build microservices
Owasp Juice Shop: Achieving sustainability for open source projects
Gradle,the new build system for android
Continuous Delivery Applied (AgileDC)
Unit Test Android Without Going Bald
Gradle: One technology to build them all
Continuous deployment
OWASP Juice Shop 5.x and beyond
Running Spring Boot Applications as GraalVM Native Images
Lean Engineering. Applying Lean Principles to Building Experiences
"How to deploy to production 10 times a day" Андрей Шумада
Tips for better CI on Android
JPQL/ JPA Activity 1
 
JIRA & Stach, The Love Story
Peering Inside the Black Box: A Case for Observability
Agile Fundamental Skill Set
Continuous Integration and PHP
はじめての JFrog Xray
Simplified CI/CD Flows for Salesforce via SFDX - Downunder Dreamin - Sydney
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...
Ad

Similar to 不只自動化而且更敏捷的Android開發工具 gradle (20)

PDF
Keeping your build tool updated in a multi repository world
PDF
Gradle(the innovation continues)
PPTX
Magic with groovy & grails
PDF
Cut your Grails application to pieces - build feature plugins
PDF
6_PDFsam_DevOps.pdf
PPTX
7 maven vsgradle
PPTX
Continuous Delivery with Spring Cloud Pipelines: Case study. - Lublin JUG
PPTX
Agile Network India | Continuous Integration & Continuous Deployment & Automa...
PDF
Mastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
PDF
Agile & ALM tools
PDF
How to Structure Your K8s GitOps Repository at Scale by Erik Berdonces - DevO...
PDF
Multi platform application deployment with urban code deploy
PDF
Continuous delivery with Spring Cloud Pipelines Case Study
PPTX
Decide for Dummies
PPTX
DECIDE for Dummies
PPTX
Continuously Break The Android
PPTX
GraniteDS vs BlazeDS
PDF
de:code 2019 DT06 vs-show どっちのVSショー
PDF
Gitlab ci e kubernetes, build test and deploy your projects like a pro
PDF
Enterprise build tool gradle
Keeping your build tool updated in a multi repository world
Gradle(the innovation continues)
Magic with groovy & grails
Cut your Grails application to pieces - build feature plugins
6_PDFsam_DevOps.pdf
7 maven vsgradle
Continuous Delivery with Spring Cloud Pipelines: Case study. - Lublin JUG
Agile Network India | Continuous Integration & Continuous Deployment & Automa...
Mastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
Agile & ALM tools
How to Structure Your K8s GitOps Repository at Scale by Erik Berdonces - DevO...
Multi platform application deployment with urban code deploy
Continuous delivery with Spring Cloud Pipelines Case Study
Decide for Dummies
DECIDE for Dummies
Continuously Break The Android
GraniteDS vs BlazeDS
de:code 2019 DT06 vs-show どっちのVSショー
Gitlab ci e kubernetes, build test and deploy your projects like a pro
Enterprise build tool gradle
Ad

Recently uploaded (20)

PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
System and Network Administraation Chapter 3
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Understanding Forklifts - TECH EHS Solution
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PPTX
history of c programming in notes for students .pptx
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PPTX
L1 - Introduction to python Backend.pptx
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
Introduction to Artificial Intelligence
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Cost to Outsource Software Development in 2025
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PPTX
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
PPTX
CHAPTER 2 - PM Management and IT Context
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
System and Network Administraation Chapter 3
Odoo POS Development Services by CandidRoot Solutions
Navsoft: AI-Powered Business Solutions & Custom Software Development
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Upgrade and Innovation Strategies for SAP ERP Customers
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Understanding Forklifts - TECH EHS Solution
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
history of c programming in notes for students .pptx
Adobe Illustrator 28.6 Crack My Vision of Vector Design
L1 - Introduction to python Backend.pptx
Softaken Excel to vCard Converter Software.pdf
Introduction to Artificial Intelligence
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Wondershare Filmora 15 Crack With Activation Key [2025
Cost to Outsource Software Development in 2025
Design an Analysis of Algorithms II-SECS-1021-03
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
CHAPTER 2 - PM Management and IT Context

不只自動化而且更敏捷的Android開發工具 gradle

Editor's Notes

  • #2: 軟體走向不外乎是軟件服務化以及雲端化計算還以mobile App,大部份公司推出產品時都是三管齊下 越來越重視與第三方套件以及工具的整合度, Gradle是近期在java-based領域廣受歡迎的建置工具,Google也在2013年開始讓gradle成為Android App開發的主要工具。 由於這些特性,如果你是java-based的使用者,gradle具體而微可以說是實踐devops不二法門。
  • #3: 1)在開始今天的主題之前,我想先請大家觀賞一小段約8分鐘的影片,再從影片的內容來切入今天的主禮。 2)這個紀錄片是紀錄2000年的時候netscape瀏覽器公司為了因應微軟IE強大的競爭壓力,計畫讓整個netscape open source, 希望透過open source能讓他的規格更普遍更能讓大家接受並使用。 開放程式碼之前,需要進行程式碼重構 修改API介面讓她更適合open source 專案,但這專案時程很趕,需要在短短幾個月內達成。 參與工程師約上百人,為了快速完成,因此他們甚至還設計一個自動化整合編譯的系統來幫助專案進行。 其實現在看起來,他就是一個持續整合概念 ! 影片中還有一些精彩的對話,例如: -他舉賣軟體和賣房地產兩個產業有什麼不同。 -還有當時netscape的工作環境也是像現在google一樣,可以讓你自由玩樂而放鬆
  • #4: Ok 抱歉,必須在故事進入高潮前停下來,反正我們都知道最後結局,IE和Mozilla最後誰是贏家?! 我們來回想一下,影片中雖然看似有自動化,但仍是窒礙難行 我們看一下這些問題的敘述: -> 這很明顯可能是版本管理或是相依性管理出了問題,而且他們缺乏一個順暢的產品流水線
  • #5: 不知道大家怎麼想,當時我看到這一段的時候,心裡面是很興奮的,我想要在辦公室也準備一支球棒… 回歸正題,上述這些問題其實拿回現代的專案開發,其實也是很常發生(除了載具從磁片變成網路之外) 接下來我們先探討什麼事暢快的產品流水線
  • #6: 1)大家知道開發程式大多喜歡用IDE,因為IDE帶給我們比較好的開發體驗,只要打錯一個錯字,都會馬上更正,這也是持續整合的一種概念 不過這只是軟體交付眾多程序中的一步而已,為了把整個產品流水線,end2end串接起來,就需要把所有環節都自動化 2) 然而自動化不僅只是將所有人工作業都寫程式取代就好了,而是要確保這是一條高品質產出的流水線, 為了讓這條流水線可以順暢的運行,有幾個要件: -我們希望它是可以重製的,這樣才能追查錯誤 -並且盡其所能地頻繁運作,並且流程透明易於分享溝通 這些都是devops 的重要觀點
  • #7: 接下來的內容我會以Android App為例,說明一些軟體交付過程中會遭遇到的問題 並且把gradle實用的解決方案整理如下,這些也都是組成暢快產品流水線的關鍵方法 Gradle也把這些解決方案稱為thoughtful conventions,他不像maven般需要遵循嚴格的規格,比較像是套用慣例,而這些conevntions也允許你彈性做調整。
  • #8: 什麼是溝通的嫌隙?
  • #9: 用現在最紅的一句話來講,就是
  • #10: 以Android App開發來說,以往開發工具有很多種,但彼此間的建置方式都不盡相同, 因此往往相同的程式碼可能會有不同的結果。 類似的溝通問題在大型分工合作的團隊便很容易出現
  • #11: Gradle的特點是讓專案可以通用一組設定,讓 command line , IDE ,以及CI server都可以通吃,一次搞定 也就是說一旦gradle build file訂定完畢,gradle保證command line與IDE就會用一樣的設定及程序來執行建置, 如果設定有調整,三方都會生效,確保大家產出一樣的結果。 這樣一來CI 系統與開發端就可以無縫銜接而沒有代溝。 然而投影片上還留有一個紅點,這邊要講的是即使工具已經統一,但仍有一種問題需要考量, 也就是商業版本與開發版本之間的差異 有時候特殊的商業需求,我們會需要將同一個軟體分成幾個不同的客制版本,這些的設定也往往在專案後期才開始定義及測試, 這樣的結果常常讓問題埋藏在專案後期才會出現。
  • #12: 問題就會越晚發生,越晚發生對專案的傷害就越大, 這只是一個有趣的示意圖而已,他不一定就是這邊指的商業版本的差異 當然增加測試的涵蓋度也是可以降低這些問題,如果這些商業版本的設定在開發開發時期就測不到呢? talk back issue (solution? lint) <Button android:id=”@+id/pause_button” android:src=”@drawable/pause” android:contentDescription=”@string/pause”/>
  • #13: 為什麼開發階段常忽略- >很麻煩 >很隱諱(可能是自己寫preprocessing來換圖或是換資源檔) >
  • #14: 一般因為不同的客戶需求,一個軟體產品可能會分為好幾個商業客製版本。 這在Android App上很常見,因為裝置類型眾多的關係 如果是手機開發商,那可能會更複雜,因為你可能還需要分T-mobile 版本 verizon版本等電信商版本等 2) Product Flavor是Google在gradle工具上所設計的APK客製方式,可以讓同一個軟體專案方便且有效率的製作出不同客製的APK(而無需做source code branch) 3) 透過這個機制可以讓不同商業版本的設定在開發工作環境就可以輕鬆實現 是讓開發維運兩端資訊對稱透明很好的做法
  • #15: 下面的例子,我們舉google 官方網站上的multi-apk範例, 在範例的程式碼目錄中,可以看分成phone與tablet以及main三個子目錄,phone與tablet便是兩個不同的product flavor。 我們可以將有差異的內容放在flavor目錄中,這個範例需要客製不同的AndroidManifest.xml(當然在現實專案還會有程式或是資源檔等) 透過support-screen來區分是table版本或是phone版本
  • #16: 範例中除了調整support-screens內容之外,我們還需要在AndroidManifest.xml中編輯不同的versionCode與versionName 1) versionCode和versionName是什麼? versionName則是所謂的軟體版本,主要是顯示給使用者/開發者看 而versionCode則是用作更新版本的判斷依據,每個APK的versionCode都需要是unique. 數字大的可以更新數字小的版本 2) 因此一旦客制APK數量變多,versionCode就會很亂,因此Google建議我們設計一個計算versionCode的schema 3) 假設這個軟體專案可能需要為不同API level以及螢幕尺寸做出不同的APK 因此schema可以設計成如上方的方式,
  • #17: 我們可以每次都手動算出versionCode並更新至AndroidManifest.xml 但這樣很容易出錯,因此我們要這些動作全都自動化 正確地做法式把處理邏輯寫在腳本語言中
  • #18: 我們可以把上述的計算versionCode的schema 透過gradle 設定檔也就是build.gradle來處理 這也是Gradle支援groovy語言優點之一,因為撰寫起來比ant等更方便且易讀,而且gradle file本身就是一個可以執行groovy的scripts file 在範例中我們定義了兩個函示來設定AndroidManifest.xml的versionCode以及versionName數值 在computeVersionCode函示中傳入int來區分phone 或是tablet,並且在productFlavors區段分別輸入不同參數來呼叫此函式 3)另外我們希望不同flavor的APK都使用相同的versionName,因此在defaultConfig區段呼叫computeVersionName函示。 在computeVersionName function中,我們還可以透過環境變數取得Jenknis build job才會產生的BUILD_NUMBER變數,便可直接將此編號編於versionName中。 http://tools.android.com/tech-docs/new-build-system/tips
  • #21: 這樣做有助於進行Dogfooding
  • #22: 或者稱為Eat your own dog food 本意是自己公司員工應該先試用自家產品的意思 試用自家產品的目的是什麼呢?當然不是要大家一起按讚
  • #23: 所以嚴格來說Dogfooding其實一個良好的版本管控策略 隨時可以發布某一個版本到員工的裝置上,如果有問題員工也能很方便指出哪個版本有什麼問題並正確地回朔程式碼來源 有新版本還能快速地更新到裝置上甚至是OTA
  • #24: (SKIP) 至於為什麼只把build number編於於versionName呢?->鼓勵盡量多執行建置,但不是每一個build都會release,因此不用影響versioncode,但每一個build都需要有一個唯一值來用於追朔問題。 如果我們鼓勵頻繁建置 每天都出現好幾十次建置,而且把build number編進versionCode的話,一下子就滿了
  • #25: SCM 版本控管伺服器 或是程式碼管理伺服器
  • #26: 這個問題也是一般新專案最常遇到的問題就是程式碼怎麼管理怎麼執行, 哪些東興應該放上SCM,哪些不用
  • #27: 在思考如何最好程式碼管理及軟體發佈流程之前,我這邊先節錄Gradle在官網上面對軟體交付的兩段詮釋 第一句話簡單意思是說,gradle希望每個開發者拿到程式碼之後,無須安裝什麼煩人的工具或是相依套件就可以直接用! 第二句的意思是說,gradle保證給個開發者都會用相同的程序以及相同的相依版本來建置專案
  • #28: 為了達成這個目的我們是不是需要把全部東西都放上SCM? 精確來講 大部份都要放上SCM
  • #29: 我們把東西放上SCM,其中一個重要目的是建立一個可靠且可重複的流程 因此建置過程的產出是不應該上傳至SCM 這樣才能確保同一版本的code可以重制(還原出)相同的binary 另外建置過程所產生的暫存檔以及任何產出也盡量不要與原始程式碼放在一起,應該讓程式碼保持乾淨的狀態
  • #30: 為了避免剛剛所提及的暫時檔被不小心放上SCM,使用gitignore是一個很好的習慣 我們在AndroidStudio或是github創建proejct的時候都會幫你設置gitignore template,大家記得要把他也上傳到版本控管伺服器上。 接下來當然我們要把所有的gradle設定檔都放上SCM,這樣子這版程式碼才能按照預期的方式產出apk build scrip as code 因此我們會需要將gradle build file上傳至SCM, 這邊會看到比較特殊的gradlew.sh這個執行擋也放上SCM了
  • #32: 接下來我們比較大的篇幅來介紹gradle的相依性管理 因為這算是gradle一個很重要的功能
  • #33: 而相依管理也可以說是android App的重頭戲? 如同開頭所講,因為雲端以及軟件服務化的關係,現在一個好用的App,通常還沒寫程式就需要先整合一堆第三方套件, 例如需要放廣告,要整合地圖又要社交化等等 因此App越來越腫
  • #34: 這些模組如果本身還有其他相依性,那就會一場惡夢
  • #35: 很明顯這裡面有很多容易出錯的人為因素
  • #36: 因為最後產出的APK中裡面就只有一個classes.dex,dex中的class是不能重複的 因此如果專案中有不圖模組各自下載了相同類別庫但檔名不同的話,就會建置失敗 甚至是檔名一樣但其實版本不同,最後也會建置失敗。 因為這邊並沒有一個對相依套件命名的統一標準也沒有版本概念 In Java, there is no standard way to tell the JVM that you are using version 3.0.5 of Hibernate, and there is no standard way to say that foo-1.0.jar depends on bar-2.0.jar
  • #37: 我們只需要在build.gradle指定所需要的類別庫名稱以及版本就好 建置的時候 maven會自動上網把類別抓加下來 神乎其技
  • #38: 問題來了,如果剛剛的這兩個dependency自己也有自己所需的相依函示庫呢? Maven會自動幫我們抓嗎? 如果這些相依有衝突的時候會怎麼處理呢?
  • #39: Gradle在這方面則提供了非常完整的功能
  • #40: 為了解決複雜的多層相依關係,Gradle所採取的方式是Transitive Dependency Management 規則很簡單,A->B B->C 也就是說若發現套件的背後還有相依關係, gradlec會像抓肉粽般一次都幫你抓起來
  • #41: 或許我們會想這種複雜的狀況很少遇到,所以不用管 我們可以看google play service這套類別庫(aar),他本身也是一複雜的相依階層
  • #42: 小技巧需要注意 Gradle的depenedency寫法是groupid+artifactoryId+ type +版本 Type是optional 不一定要指定,如果寫了,會預設不會啟動transitive功能
  • #43: 如果你是一個類別庫的提供者,你希望別人使用的時候也可以享用遞移式的相依管理功能 那transitive denpendency背後是怎麼運作的呢?
  • #44: 剛提到整個相依階層中有版本衝突時,gradle是怎麼處理的呢?
  • #46: Gradle offers the following conflict resolution strategies: Newest: The newest version of the dependency is used. This is Gradle's default strategy, and is often an appropriate choice as long as versions are backwards-compatible. Fail: A version conflict results in a build failure. This strategy requires all version conflicts to be resolved explicitly in the build script. See ResolutionStrategy for details on how to explicitly choose a particular version. While the strategies introduced above are usually enough to solve most conflicts, Gradle provides more fine-grained mechanisms to resolve version conflicts: Configuring a first level dependency as forced. This approach is useful if the dependency in conflict is already a first level dependency. See examples inDependencyHandler. Configuring any dependency (transitive or not) as forced. This approach is useful if the dependency in conflict is a transitive dependency. It also can be used to force versions of first level dependencies. See examples in ResolutionStrategy Dependency resolve rules are an incubating feature introduced in Gradle 1.4 which give you fine-grained control over the version selected for a particular dependency. To deal with problems due to version conflicts, reports with dependency graphs are also very helpful. Such reports are another feature of dependency management. https://docs.gradle.org/current/userguide/dependency_management.html
  • #47: https://docs.gradle.org/current/userguide/dependency_management.html
  • #48: 這邊要注意的是 如果一旦軟體交付開始要上建置系統,就應該always指定固定版本, 否則就會違反可重製原則,讓同一版程式碼產出不同的結果產出