編輯:關於Android編程
一、環境分離簡介
每個App項目,至少都會有兩個環境:測試環境和生產環境。多的甚至有四個環境:開發環境、測試環境、預生產環境和生產環境。開發人員經常需要在環境之間切換,測試人員也同樣。經常出現測試人員今天需要測試環境的最新版本,叫App開發人員打包一個給她,明天需要切換到生產版本,再叫App開發人員打包一個生產環境的給她。我們知道,一個App,在一台手機上要麼只能是測試環境的,要麼只能是生產環境的。測試人員要測試兩個環境,只能不斷替換不同環境的同個App,這實在太麻煩了。為了解決此問題,最好的方案就是環境分離,不同環境有不同的App。
但對於Android App來講,相同包名的apk在同一個設備上只能存在一個。所以我們無法做到在同一個設備上同時安裝生產環境和測試環境的安裝包,這對於日常的開發工作和測試人員的測試工作極不方便。總不能將整個工程復制一份,再通過修改包名的方式打包出另一個apk吧。所以在這種情況下,以往常見的做法就是在app中提供一個隱形的入口,供內部人員切換服務器地址,然後通過以下代碼重啟App:
private void restartApp(){ Intent intent = getContext().getPackageManager().getLaunchIntentForPackage(getContext().getPackageName()); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); }
顯然,這種做法也只是一種緩兵之計,多少還是有些不盡人意。然而,值得慶幸地是,進入Android Studio時代後,Google開始使用引入Gradle構建系統,applicationId的出現使得環境分離的問題迎刃而解。
二、package 與 applicationId
在使用Eclipse開發Apk或舊版本的Gradle構建系統中,應用的包名由AndroidManifest.xml文件中package屬性決定。同時,這個package還被用來定義命名被引用的資源類R文件。
但是在新的Android Gradle構建系統中,package屬性的兩大作用得到了解藕:applicationId作為應用的唯一標識符(包名),用於區分不同應用;package屬性定義資源類R文件,用於引用。
applicationId存在於app/build.gradle文件中的defaultConfig配置下,新建項目時默認使用package屬性值初始化,所以如果沒有特殊的需求,一般我們不會在意和修改這個值:
apply plugin: 'com.android.application' android { compileSdkVersion 19 buildToolsVersion "19.1" defaultConfig { applicationId "com.example.my.app" minSdkVersion 15 targetSdkVersion 19 versionCode 1 versionName "1.0" } ...
所以,要實現Apk的環境分離,也就是在同一設備上安裝同一應用的不同版本,從本質上我們要修改applicationId的值,構建打包出不同包名的apk安裝文件。Gradle構建系統提供了兩種方式供開發人員修改applicationId的值,productFlavors和buildTypes,通過這兩個方式我們可以輕松實現apk的打包定制,或者說Build Variants(構建變種)。
三、Build Variants
項目的productFlavors和buildTypes配置可以在app/build.gradle代碼文件或者Project Structure上修改,作用是一樣的。
四、productFlavors
項目可以通過定義多個不同的productFlavors來實現應用的不同定制版本,每一個Flavor與buildTypes配合產出對應的一種輸出類型的apk文件,新建的項目初始化只有一個默認的Flavor:defaultConfig
注意:默認的defaultConfig為新建的productFlavors提供基本的配置,也就說,productFlavors的配置會覆蓋defaultConfig中相同的屬性,從而實現產品的不同定制版輸出。對於環境分離,這裡可以通過定義新的applicationId屬性來實現。
五、buildTypes
默認情況下,項目的buildTypes包含debug和release兩個構建版本,其中release版本的執行需要手動設置簽名文件。對於環境分離,與productFlavors不同的是,buildTypes通過定義applicationIdSuffix來實現的,即添加後綴名:
除了這些可配置的屬性外,productFlavors和buildTypes都會通過各自的sourceSet來提供代碼和資源,默認的路徑為:src/flavorName和src/typeName。利用這個特性,我們可以實現不同定制版本的apk顯示不同的應用名稱和桌面圖標,以便從設備上進行區分。
productFlavors和buildTypes配合產出各種格式為“flavorName + typeName”的Build Variants,以打包出不同版本的apk。當你沒有自定義flavors,默認的defaultConfig也會與buildTypes形成對應的Build Variants,只是沒有名字,所以顯示為debug和release。比如這段配置:
android { ... productFlavors{ beta{ applicationId 'com.yifeng.mdstudysamples.beta' } production{ applicationId 'com.yifeng.mdstudysamples' } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix '.debug' } } }
我們配置了beta和production兩種productFlavors,release和debug兩種buildTypes。所以,對應的Build Variants就有四種,分別為:betaDebug、betaRelease、productionDebug和productRelease。可以在Build Variants窗口查看並選擇對應的構建類型運行應用:
注意:前面提到,buildTypes通過添加後綴的方式修改applicationId(包名)的,換句話說,就是在productFlavors的基礎上修改包名的。所以,在上面這個例子中,betaRelease構建類型打包出的apk文件的包名是:com.yifeng.mdstudysamples.beta.debug。
五、實現方式
通過上面這些介紹,基本上大家能夠知道在Android上如何實現app的環境分離了。我們可以選擇使用productFlavors和buildTypes這兩種方式在同一個設備上來安裝同一個應用的不同版本。他們道理上是一樣的,只是相比之下,使用buildTypes不用新建productFlavors,更為方便。這裡我就buildTypes為例簡單描述一下環境分離的實現。
1.對於一個默認productFlavors和buildTypes配置的項目,我們修改debug配置的applicationIdSuffix屬性,設為".debug"(名字可以隨意設置),release版本不用變動。
android { ... buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix '.debug' } } }
有了這一步,已經能夠將debug版本和release的apk安裝在同一個設備上了。還可以做到更好,比如修改debug版本的桌面圖標、應用名稱等,便於區分。
2.我們在src目錄下新建一個debug目錄,將main目錄下的res目錄復制一份到debug目錄下,修改各個分辨率下的桌面Icon和strings.xml文件中的應用名稱,加個debug標識。目錄結構如圖所示:
在構建打包時,debug目錄下的res資源采用疊加的方式合並到main裡面去,並替換相同的內容,而這個例子只需要修改桌面Icon和應用名稱,所以這裡我只復制了res目錄下的相關文件,其他文件並未復制。
3.修改代碼裡的服務器接口地址,選擇對應的Build Variants類型,運行即可。其實也可以在debug和main目錄下的string.xml資源文件中定義服務器地址,然後在程序的入口處賦值給代碼裡的全局靜態變量。
總結
以上就是這篇文章的全部內容了,希望能對大家的學習或者工作帶來一定的幫助,如果有疑問大家可以留言交流。
在前一篇文章中(一步一步教你在 Android 裡創建自己的賬號系統(一)),我向大家介紹了如何在 Android 系統中創建自己的賬戶系統,
要逆向分析並修改一個Android應用,首先是對APK進行解包和打包,這一部分網上資料鋪天蓋地,不再贅述了。值得一提的一點就是,如果apktool無法解包或打包的話,可以
最近我嘗試使用ViewPager+GridView實現的,看起來一切正常,廢話不多說,具體代碼如下:如圖是效果圖 首先分析下思路1.首先是怎麼布局:整體是一個V
Android-webview和js互相調用Android 和 H5 都是移動開發應用的非常廣泛。市面上很多App都是使用Android開發的,但使用Android來開發