如題所示!本篇文章就是爲了解決這種問題。方便打包和運行的時候能作到無需手動替換配置,便可打包想要的apk。打包的時候,只需選一下想打哪一種配置的apk就OK啦。 (^o^)/~java
先來看,有需求以下:react
解決思路android
productFlavors
來配置渠道,這裏我將渠道用來表示哪一種apk,以下我須要配置四種應用:productFlavors { userquhua {} quhua {} cuntuba {} xemh {} }
signingConfigs
中配置多個(我將全部簽名文件放在了項目跟目錄的key文件夾中),這樣咱們就能夠經過signingConfigs
指定預製好的簽名配置。signingConfigs { userquhuaRelease { storeFile file("../key/xxx1.keystore") storePassword "xxxxxx" keyAlias "alias" keyPassword "xxxxxx" } quhuaRelease { storeFile file("../key/xxx2.keystore") storePassword "xxxxxx" keyAlias "alias" keyPassword "xxxxxx" } cuntubaRelease { storeFile file("../key/xxx3.keystore") storePassword "xxxxxx" keyAlias "alias" keyPassword "xxxxxx" } xemhRelease { storeFile file("../key/xxx4.keystore") storePassword "xxxxxx" keyAlias "alias" keyPassword "xxxxxx" } }
defaultConfig {}
中定義了:buildConfigField "String", "SERVER_URL", '"http://xx.xxxx.com/"'
manifest
標籤裏的,package
的值,假如是:com.xxx.xx
import com.xxx.xx.BuildConfig;
BuildConfig.SERVER_URL
它的值就是上邊配置的字符串:http://xx.xxxx.com/
。git
BuildConfig
看一看,裏面還包含了一些當前的包名版本號等信息。// 省略其餘配置... android { // 省略其餘配置... productFlavors { userquhua { applicationId "com.xxx.xx" versionCode 1 versionName "1.0.0" signingConfig signingConfigs.userquhuaRelease // 配置簽名 String qq_id = '"xxxxxxxxx"' //配置qq appid buildConfigField "String", "QQ_ID", qq_id buildConfigField "String", "WX_ID", '"wxxxxxxxxxxxxxxxxx"' // 配置微信appid manifestPlaceholders = [ qq_id: qq_id, JPUSH_PKGNAME : applicationId, JPUSH_APPKEY : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", //JPush 上註冊的包名對應的 Appkey. JPUSH_CHANNEL : "developer-default", ] } } buildTypes { release { // 省略其餘配置... signingConfig null // 置空 } debug { // 省略其餘配置... signingConfig null // 置空 } } }
com.xxx.xx
,版本號爲1
,版本名爲1.0.0
。BuildConfig
調用QQ_ID
靜態常量,就是該渠道里配置的值,WX_ID
同理。manifestPlaceholders
配置也能夠這樣配置。buildTypes
中的簽名配置signingConfig
若是不設置爲null
,那麼打包的是有仍是之內置的簽名打包。xemh
渠道的資源目錄所有展開一下。app_name
修改既可替換app下strings的app_name
,其餘不用替換的不用寫就行。獲取當前時間github
static def releaseTime() { return new Date().format("yyyy-MM-dd-HH.mm", TimeZone.getTimeZone("GMT+8")) }
打包的時候,修改文件名,以方便區別渠道和版本打包時間spring
applicationVariants.all { variant -> variant.outputs.all { outputFileName = "${variant.productFlavors[0].name}-v${variant.productFlavors[0].versionName}-${releaseTime()}.apk" } }
${variant.productFlavors[0].name}
當前渠道名${variant.productFlavors[0].versionName}
當前版本名${releaseTime()}
當前時間若是您在清單文件AndroidManifest.xml
中,有那種以包名開頭命名的那種。由於若是包名都改了,有些也須要動態的改變。能夠用${applicationId}
代替。在打包的時候,會自動替換成當前包名。服務器
好比,相似下配置:微信
<permission android:name="com.xxx.xx.permission.JPUSH_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.xxx.xx.permission.JPUSH_MESSAGE" /> <receiver android:name=".push.MyJPushMessageReceiver" android:enabled="true" android:exported="false" > <intent-filter> <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" /> <category android:name="com.xxx.xx" /> </intent-filter> </receiver> <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.xxx.xx.provider" android:exported="false" tools:replace="android:authorities" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
可改成:app
<permission android:name="${applicationId}.permission.JPUSH_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE" /> <receiver android:name=".push.MyJPushMessageReceiver" android:enabled="true" android:exported="false" > <intent-filter> <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" /> <category android:name="${applicationId}" /> </intent-filter> </receiver> <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" tools:replace="android:authorities" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
固然值得注意的是,在代碼中咱們也不能把包名寫死了,可經過
BuildConfig
獲得當前包名maven
有關隱私信息的都用xxx替換了
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.0.0' classpath "io.github.prototypez:save-state:0.1.7" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() maven { url "https://jitpack.io" } maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' } flatDir { dirs 'libs' } } } task clean(type: Delete) { delete rootProject.buildDir } ext{ minSdkVersion = 16 targetSdkVersion = 27 compileSdkVersion = 27 buildToolsVersion = '27.1.1' supportLibraryVersion = '27.1.1' xmvpVersion = '1.2.2' retrofit2Version = '2.3.0' okhttp3Version = '3.8.1' butterknifeVersion = '8.6.0' rx2Version = '2.0.2' CircleProgressDialogVersion = '1.0.2' smarttabVersion = '1.6.1@aar' adapterHelperVersion = '2.9.41' glideVersion = '4.7.1' roundedimageviewVersion = '2.3.0' eventbusVersion = '3.0.0' dispatcherVersion = '2.4.0' picture_libraryVersion = 'v2.2.3' statusbarutilVersion = '1.5.1' okhttpUtilsVersion = '3.8.0' constraintVersion = '1.1.3' flexboxVersion = '1.0.0' }
build.gradle
apply plugin: 'com.android.application' apply plugin: 'save.state' static def releaseTime() { return new Date().format("yyyy-MM-dd-HH.mm", TimeZone.getTimeZone("GMT+8")) } android { compileSdkVersion rootProject.compileSdkVersion // buildToolsVersion rootProject.buildToolsVersion defaultConfig { minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true // config the JSON processing library javaCompileOptions { annotationProcessorOptions { arguments = [ serializer : "gson" ] } } ndk { abiFilters "armeabi-v7a" } renderscriptTargetApi 25 renderscriptSupportModeEnabled true } signingConfigs { userquhuaRelease { storeFile file("../key/xxx.keystore") storePassword "xxxxxx" keyAlias "xxx" keyPassword "xxxxxx" } quhuaRelease { storeFile file("../key/xxx.keystore") storePassword "xxxxxxx" keyAlias "xxx" keyPassword "xxxxxxx" } cuntubaRelease { storeFile file("../key/xxx.keystore") storePassword "xxxxxxx" keyAlias "xxx" keyPassword "xxxxxxx" } xemhRelease { storeFile file("../key/xxx.keystore") storePassword "xxxxxxx" keyAlias "xxx" keyPassword "xxxxxxx" } } flavorDimensions "default" productFlavors { userquhua { applicationId "com.xxx.xx" versionCode 22 versionName "1.7.5" signingConfig = signingConfigs.userquhuaRelease String qq_id = '"xxxxxx"' buildConfigField "String", "QQ_ID", qq_id // qq appId buildConfigField "String", "SINA_ID", '"xxxxxx"' // 新浪appId buildConfigField "String", "WX_ID", '"xxxxxx"' // 微信 appId buildConfigField "String", "UM_ID", '"xxxxxx"' // 友盟 buildConfigField "String", "WX_SECRET", '"xxxxxx"' // 微信 secret buildConfigField "String", "SINA_REDIRECT", '"http://open.weibo.com/apps/xxxxxx/privilege/oauth"' // 新浪 buildConfigField "String", "ADHUB_INIT_ID", '"xxxxxx"' // 廣告sdk初始化id buildConfigField "String", "ADHUB_SPLASH_ID", '"xxxxxx"' // 開屏廣告id buildConfigField "String", "ADHUB_BANNER_ID", '"xxxxxx"' // banner廣告id buildConfigField "String", "SERVER_URL", '"http://xxx.xxx.com/"' buildConfigField "String", "LOGO_URL", '"http://file.xxx.com/img/xxx.png"' manifestPlaceholders = [ qq_id: qq_id, JPUSH_PKGNAME : applicationId, JPUSH_APPKEY : "xxxxxx", //JPush 上註冊的包名對應的 Appkey. JPUSH_CHANNEL : "developer-default", //暫時填寫默認值便可. ] } quhua { applicationId "com.xxx.xx" versionCode 1 versionName "1.0.0" signingConfig = signingConfigs.quhuaRelease String qq_id = '"xxxxxx"' buildConfigField "String", "QQ_ID", qq_id buildConfigField "String", "SINA_ID", '"xxxxxx"' buildConfigField "String", "WX_ID", '"xxxxxx"' buildConfigField "String", "UM_ID", '"xxxxxx"' buildConfigField "String", "WX_SECRET", '"xxxxxx"' buildConfigField "String", "SINA_REDIRECT", '"http://open.weibo.com/apps/xxxxxx/privilege/oauth"' buildConfigField "String", "ADHUB_INIT_ID", '"xxxxxx"' // 廣告sdk初始化id buildConfigField "String", "ADHUB_SPLASH_ID", '"xxxxxx"' // 開屏廣告id buildConfigField "String", "ADHUB_BANNER_ID", '"xxxxxx"' // banner廣告id buildConfigField "String", "SERVER_URL", '"http://xx.xxx.com/"' buildConfigField "String", "LOGO_URL", '"http://file.xxx.com/img/xxx.png"' manifestPlaceholders = [ qq_id: qq_id, JPUSH_PKGNAME : applicationId, JPUSH_APPKEY : "xxxxxx", //JPush 上註冊的包名對應的 Appkey. JPUSH_CHANNEL : "developer-default", //暫時填寫默認值便可. ] } cuntuba { applicationId "com.xxx.xx" versionCode 1 versionName "1.0.0" signingConfig = signingConfigs.cuntubaRelease String qq_id = '"xxxxxx"' buildConfigField "String", "QQ_ID", qq_id buildConfigField "String", "SINA_ID", '"xxxxxx"' buildConfigField "String", "WX_ID", '"xxxxxx"' buildConfigField "String", "UM_ID", '"xxxxxx"' buildConfigField "String", "WX_SECRET", '"xxxxxx"' buildConfigField "String", "SINA_REDIRECT", '"http://open.weibo.com/apps/xxxxxx/privilege/oauth"' buildConfigField "String", "ADHUB_INIT_ID", '"xxxxxx"' // 廣告sdk初始化id buildConfigField "String", "ADHUB_SPLASH_ID", '"xxxxxx"' // 開屏廣告id buildConfigField "String", "ADHUB_BANNER_ID", '"xxxxxx"' // banner廣告id buildConfigField "String", "SERVER_URL", '"http://xxx.xxxx.com/"' buildConfigField "String", "LOGO_URL", '"http://file.xxx.com/img/xxx.png"' manifestPlaceholders = [ qq_id: qq_id, JPUSH_PKGNAME : applicationId, JPUSH_APPKEY : "xxxxxx", //JPush 上註冊的包名對應的 Appkey. JPUSH_CHANNEL : "developer-default", //暫時填寫默認值便可. ] } xemh { applicationId "com.xxx.xx" versionCode 1 versionName "1.0.0" signingConfig = signingConfigs.xemhRelease String qq_id = '"xxxxxx"' buildConfigField "String", "QQ_ID", qq_id buildConfigField "String", "SINA_ID", '"xxxxxx"' buildConfigField "String", "WX_ID", '"xxxxxx"' buildConfigField "String", "UM_ID", '"xxxxxx"' buildConfigField "String", "WX_SECRET", '"xxxxxx"' buildConfigField "String", "SINA_REDIRECT", '"xxxxxx"' buildConfigField "String", "ADHUB_INIT_ID", '"xxxxxx"' // 廣告sdk初始化id buildConfigField "String", "ADHUB_SPLASH_ID", '"xxxxxx"' // 開屏廣告id buildConfigField "String", "ADHUB_BANNER_ID", '"xxxxxx"' // banner廣告id buildConfigField "String", "SERVER_URL", '"http://xx.xxx.com/"' buildConfigField "String", "LOGO_URL", '"http://file.xxxxxx.com/img/xxxxxx.png"' manifestPlaceholders = [ qq_id: qq_id, JPUSH_PKGNAME : applicationId, JPUSH_APPKEY : "xxxxxx", //JPush 上註冊的包名對應的 Appkey. JPUSH_CHANNEL : "developer-default", //暫時填寫默認值便可. ] } } applicationVariants.all { variant -> variant.outputs.all { outputFileName = "${variant.productFlavors[0].name}-v${variant.productFlavors[0].versionName}-${releaseTime()}.apk" } } buildTypes { release { // 不顯示Log buildConfigField "boolean", "LOG_DEBUG", "false" signingConfig null minifyEnabled true zipAlignEnabled true // 移除無用的resource文件 shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { // 顯示Log buildConfigField "boolean", "LOG_DEBUG", "true" signingConfig null minifyEnabled false zipAlignEnabled false shrinkResources false } } packagingOptions { exclude 'META-INF/DEPENDENCIES.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/LICENSE' exclude 'META-INF/LICENSE.txt' } compileOptions { targetCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8 } dexOptions { javaMaxHeapSize "4g" //此處可根據電腦自己配置 數值越大 固然越快 preDexLibraries = false } } repositories { flatDir { dirs 'libs', '../adpoymer/libs' } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation "com.android.support:appcompat-v7:$supportLibraryVersion" implementation "com.android.support:recyclerview-v7:$supportLibraryVersion" implementation "com.android.support:support-v4:$supportLibraryVersion" implementation "com.android.support:design:$supportLibraryVersion" implementation "com.android.support.constraint:constraint-layout:$constraintVersion" //添加retrofit2 的依賴 添加這個依賴就默認添加了okhttp依賴 compile "com.squareup.retrofit2:retrofit:$retrofit2Version" compile "com.squareup.retrofit2:converter-gson:$retrofit2Version" compile "com.squareup.retrofit2:adapter-rxjava2:$retrofit2Version" compile "com.squareup.okhttp3:logging-interceptor:$okhttp3Version" compile "com.jakewharton:butterknife:$butterknifeVersion" annotationProcessor "com.jakewharton:butterknife-compiler:$butterknifeVersion" compile "io.reactivex.rxjava2:rxandroid:$rx2Version" compile "com.github.xujiaji:xmvp:$xmvpVersion" implementation "com.github.autume:CircleProgressDialog:$CircleProgressDialogVersion" compile "com.ogaclejapan.smarttablayout:library:$smarttabVersion" compile "com.github.CymChad:BaseRecyclerViewAdapterHelper:$adapterHelperVersion" compile "com.github.bumptech.glide:glide:$glideVersion" annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion" compile "com.makeramen:roundedimageview:$roundedimageviewVersion" compile "org.greenrobot:eventbus:$eventbusVersion" annotationProcessor "com.github.hotchemi:permissionsdispatcher-processor:$dispatcherVersion" compile "com.jaeger.statusbarutil:library:$statusbarutilVersion" compile("com.github.hotchemi:permissionsdispatcher:$dispatcherVersion") { exclude module: "support-v13" } implementation "com.github.LuckSiege.PictureSelector:picture_library:$picture_libraryVersion" implementation 'me.drakeet.library:crashwoodpecker:2.1.1' implementation 'com.github.chenupt.android:springindicator:1.0.2@aar' debugImplementation 'com.amitshekhar.android:debug-db:1.0.4' implementation 'com.umeng.sdk:common:1.5.3' implementation 'com.umeng.sdk:analytics:7.5.3' implementation 'com.liulishuo.filedownloader:library:1.7.5' implementation project(':banner') implementation project(':xdialog') implementation project(':shareutil') implementation project(':update') implementation project(':pay') // implementation project(':adhub') implementation project(':imagewatcher') implementation files('libs/lite-orm-1.9.2.jar') implementation 'jp.wasabeef:blurry:2.1.1' implementation "com.google.android:flexbox:$flexboxVersion" implementation 'cn.jiguang.sdk:jpush:3.1.6' // 此處以JPush 3.1.6 版本爲例。 implementation 'cn.jiguang.sdk:jcore:1.2.5' // 此處以JCore 1.2.5 版本爲例。 compile(name: 'sdk-release', ext: 'aar') compile(name: 'open_ad_sdk', ext: 'aar') compile(name: 'adpoymer-3.4.35', ext: 'aar') implementation 'pl.droidsonroids.gif:android-gif-drawable:1.0.+' }
https://github.com/xujiaji/OneForAllApk
就這樣就能夠解放大量勞動力啦!每次項目打包各類軟件,選一下就ojbk,哈哈哈~ 若是有些配置在其餘渠道沒有的,也可經過BuildConfig在java中判斷若是是某某渠道那麼屏蔽。 原文地址:https://blog.xujiaji.com/post/android-project-one-for-more over