日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在平時的Android開發中,我們經常會遇到在不同網絡環境(比如:開發環境、測試環境)之間的切換、一次打多個渠道包等需求,如何優雅的管理網絡環境的配置?如何快速的打出多個渠道包?這是一個值得研究的問題。

如果每一次在不同網絡環境間切換,都需要更改代碼,然而重新打包,那未免有點低效。下面是我的實踐探索,看網上很多人都是根據buildType來切換網絡環境,感覺有點不好,因為網絡環境可能很多種,而buildType我們一般是2種,而且,不同網絡環境的包最好能同時安裝在手機上,以便我們調試。最好,我一看這個包的名稱和圖標,就能知道這是什么環境的包。

一、概述

1.多版本

基于buildTypes

(1)debug:調試版本,無混淆

(2)release:發布版本,有混淆、壓縮

2.多環境

基于productFlavors

(1)develop:開發環境,開發和自測時使用

(2)check:測試環境,克隆一份生產環境的配置,在這里測試通過后,再發布到生產環境。

之所以沒命名為test是因為在gradle編譯時:ProductFlavor names cannot start with 'test'

(3)product:生產環境,正式提供服務的。

3.多渠道

基于Android新的應用簽名方案APK Signature Scheme v2中的APK Signing Block區塊

我這里使用的是美團封裝的Walle庫。使用Walle庫請確保你的Android Gradle 插件版本在2.2.0以上。

為什么不直接使用productFlavors來打包多渠道?因為productFlavors打多渠道包太慢了,打30個包差不多十幾分鐘,無法忍受!

為什么不使用美團之前基于META-INF進行渠道標識的方案?因為Android7.0之后的這種黑科技已經失效了!

二、示例

1、配置build.gradle

(1) 在位于項目的根目錄 build.gradle 文件中添加Walle Gradle插件的依賴, 如下:

buildscript {
 dependencies {
 classpath 'com.android.tools.build:gradle:2.2.3'
 classpath 'com.meituan.android.walle:plugin:1.0.3'
 }
}

(2) 在當前App的 build.gradle 文件中apply這個插件,并添加上用于讀取渠道號的aar

apply plugin: 'com.android.application'
apply plugin: 'walle'
android {
 compileSdkVersion 25
 buildToolsVersion "25.0.2"
 defaultConfig {
 minSdkVersion 15
 targetSdkVersion 25
 versionCode 1
 versionName "1.0"
 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
 }
 signingConfigs {
 release {
 keyAlias KEY_ALIAS
 keyPassword KEY_PASSWORD
 storeFile rootProject.file(KEYSTORE_FILE)
 storePassword KEYSTORE_PASSWORD
 }
 }
 buildTypes {
 //調試版本,無混淆
 debug {
 minifyEnabled false
 signingConfig signingConfigs.release
 }
 //發布版本,有混淆
 release {
 minifyEnabled true
 zipAlignEnabled true
 shrinkResources true
 signingConfig signingConfigs.release
 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 }
 }
 productFlavors {
 //開發環境
 develop {
 buildConfigField "int", "ENV_TYPE", "1"
 applicationId 'om.soubu.walledemo.develop'
 manifestPlaceholders = [
 app_name: "開-WalleDemo",
 app_icon: "@drawable/icon_develop"
 ]
 }
 //測試環境
 check {
 buildConfigField "int", "ENV_TYPE", "2"
 applicationId 'om.soubu.walledemo.check'
 manifestPlaceholders = [
 app_name: "測-WalleDemo",
 app_icon: "@drawable/icon_check"
 ]
 }
 //生產環境
 product {
 buildConfigField "int", "ENV_TYPE", "3"
 applicationId 'com.soubu.walledemo.product'
 manifestPlaceholders = [
 app_name: "WalleDemo",
 app_icon: "@drawable/icon_product"
 ]
 }
 }
}
dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
 exclude group: 'com.android.support', module: 'support-annotations'
 })
 compile 'com.android.support:appcompat-v7:25.1.0'
 testCompile 'junit:junit:4.12'
 compile 'com.meituan.android.walle:library:1.0.3'
}

(3) 這里,我根據不同的環境生成了不同包名的apk,方便在手機上同時安裝多個環境的應用。為了讓gradle動態更改apk的名稱和圖標,我們需要在manifest文件中使用

 

Android打包之多版本、多環境、多渠道

 

 

{app_name}等占位符

<?xml%20version="1.0"%20encoding="utf-8"?>
<manifest%20xmlns:android="http://schemas.android.com/apk/res/android"
%20package="com.soubu.walledemo">
%20<application
%20android:allowBackup="true"
%20android:icon="${app_icon}"
%20android:label="${app_name}"
%20android:supportsRtl="true"
%20android:theme="@style/AppTheme">
%20<activity%20android:name=".MainActivity">
%20<intent-filter>
%20<action%20android:name="android.intent.action.MAIN"/>
%20<category%20android:name="android.intent.category.LAUNCHER"/>
%20</intent-filter>
%20</activity>
%20</application>
</manifest>

(4)%20在代碼中獲取多渠道信息

String%20channel%20=%20WalleChannelReader.getChannel(getApplicationContext());

(5)%20在代碼中獲取多環境信息

int%20envType%20=%20BuildConfig.ENV_TYPE;

這里的BuildConfig是由gradle動態生成的:

package%20com.soubu.walledemo;
public%20final%20class%20BuildConfig%20{
%20public%20static%20final%20boolean%20DEBUG%20=%20Boolean.parseBoolean("true");
%20public%20static%20final%20String%20APPLICATION_ID%20=%20"om.soubu.walledemo.develop";
%20public%20static%20final%20String%20BUILD_TYPE%20=%20"debug";
%20public%20static%20final%20String%20FLAVOR%20=%20"develop";
%20public%20static%20final%20int%20VERSION_CODE%20=%201;
%20public%20static%20final%20String%20VERSION_NAME%20=%20"1.0";
%20//%20Fields%20from%20product%20flavor:%20develop
%20public%20static%20final%20int%20ENV_TYPE%20=%201;
}

而ENV_TYPE這個字段其實就來自于我們的build.gradle:

%20productFlavors%20{
%20//開發環境
%20develop%20{
%20buildConfigField%20"int",%20"ENV_TYPE",%20"1"
%20applicationId%20'om.soubu.walledemo.develop'
%20manifestPlaceholders%20=%20[
%20app_name:%20"開-WalleDemo",
%20app_icon:%20"@drawable/icon_develop"
%20]
%20}
%20{

這里我們最好定義一個常量類區分這些環境的類型:

public%20class%20EnvType%20{
%20public%20static%20final%20int%20DEVELOP%20=%201;//開發環境
%20public%20static%20final%20int%20CHECK%20=%202;//測試環境
%20public%20static%20final%20int%20PRODUCT%20=%203;//正式環境
}

2、打包多環境

這里我們直接執行assemble命令,打包所有的buildType*productFlavors

 

 

 

或者使用命令行也可以:

gradle assemble

執行結果:26秒搞定6個包:2個版本*3個環境

 

Android打包之多版本、多環境、多渠道

 

 

Android打包之多版本、多環境、多渠道

 

 

這里我們可以看到debug包都是1.4M,而release包都是0.7M,顯然,我們的混淆和壓縮配置是生效了的,雖然這里我并沒寫混淆規則

 

Android打包之多版本、多環境、多渠道

 

 

Android打包之多版本、多環境、多渠道

 

 

我們分別安裝3個環境的包到自己的手機上:

 

Android打包之多版本、多環境、多渠道

 

 

看三個包的名稱和圖標都不一樣,顯然我們之前在manifest文件中配置的占位符生效了。

然后我們點進去分別看看這3個app的區別:

 

Android打包之多版本、多環境、多渠道

 

 

Android打包之多版本、多環境、多渠道

 

 

Android打包之多版本、多環境、多渠道

 

 

這樣,我們就可以在代碼中,根據環境字段envType的不同,來選擇不同的網絡環境了。

界面的代碼如下:

public class MainActivity extends AppCompatActivity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 TextView tvEnv = (TextView) findViewById(R.id.tv_env);
 TextView tvChannel = (TextView) findViewById(R.id.tv_channel);
 TextView tvPackage = (TextView) findViewById(R.id.tv_package);
 String channel = WalleChannelReader.getChannel(this.getApplicationContext());
 int envType = BuildConfig.ENV_TYPE;
 String packageName = getPackageName();
 switch (envType) {
 case EnvType.DEVELOP:
 tvEnv.setText("envType=" + "開發環境");
 break;
 case EnvType.CHECK:
 tvEnv.setText("envType=" + "測試環境");
 break;
 case EnvType.PRODUCT:
 tvEnv.setText("envType=" + "生產環境");
 break;
 }
 tvChannel.setText("channel=" + channel);
 tvPackage.setText("package=" + packageName);
 }
}

3、打包多渠道

在Project的根目錄下新建channel文件:

anzhi #安智
baidu #百度
huawei #華為
oppo #oppo
wdj #豌豆莢
xiaomi #小米
yyb #應用寶

執行gradle命令:

(1) 打包文件內的渠道包

gradle assembleProductRelease -PchannelFile=channel

(2) 打包自定義數組內的渠道包

gradle assembleProductRelease -PchannelList=qihu,vivo,lenovo

關于Walle庫的更多使用:詳見Github-walle

運行結果:17秒搞定8個包:1個默認包+7個渠道包

 

Android打包之多版本、多環境、多渠道

 

 

Android打包之多版本、多環境、多渠道

 

 

最后,奉上源碼:WalleDemo

常見問題

1、找不到簽名文件的配置?

 

Android打包之多版本、多環境、多渠道

 

 

汗,因為我的Demo中并沒有上傳我的jks文件,你可以添加自己的jks文件,然后在gradle.properties里面配置好簽名文件的密碼即可

在gradle.properties添加簽名文件的配置key-value

 

Android打包之多版本、多環境、多渠道

 

 

在build.gradle中引用配置的key

 

Android打包之多版本、多環境、多渠道

 

 

2、develop、check、product,如果直接run代碼,怎么設置默認的環境?

點擊查看AndroidStudio左下角的BuildVariants,然后選擇設置默認的run環境即可。

BuildVariants= buildTypes* productFlavors

 

Android打包之多版本、多環境、多渠道

 

 

 

 

分享到:
標簽:Android
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定