Androidモジュール化プロセスにおけるマルチチャネルコンパイル
6251 ワード
ある賛微商城APPグループはモジュール化の過程でPOS機関連の業務をすべて抽出する必要があるが、POS機の適合コードは複数の業務moduleの中に散らばっているので、モジュール化の過程で本当のマルチチャネルコンパイルに触れた.
余計なことは言わないで、本題に入って、解決策をみんなに分かち合って、友达が回り道をしないことを望んでいます.
では、いつ仲間は私が直面した問題に直面しますか?あなたのプロジェクトはモジュール化され、ビジネスコードは独立したlibraryの に抽出されました. libraryコードでは、 まず、現在のソリューションを出します.
現在、プロジェクトには多くのルートがありますが、ここでは主にプロジェクトに接続されているPOS機ルート-iboxpay、sunmi、weiposに注目します.私たちのビジネスコードでは、異なるflavorによって異なる機能を実現する必要があります.
メインエンジニアリングの
POS機業務と一般業務を区別するためには、コンパイル時に具体的なtask nameに従って区別する必要がある.例えばtaskが
注意:ここでは大文字と小文字の問題に注意し、Summiはsunmiで代用できません.
このように
くりを一つあげる
この例は商品moduleです.このlibraryではbuildです.gradleでもappのgradleと同じProductFlavorを定義する必要があります.
これらのflavorを書き終わったら、
なぜcustomFlavorがないのかという仲間がいるかもしれませんが、baidu、wandoujiaなどのカスタムチャネルで使用されているビジネスコードはfullというflavorと同じなので、moduleのbuildでは再び必要ありません.gradleで定義しました.
appのbuild.gradleと商品libraryのbuild.gradleが上記のように構成されている場合、terminalで実行します./gradlew assembleDebugは、full、sunmi、iboxpay、weiposの4つのチャネルのapkをスムーズにパッケージ化できます.
まとめ
ソリューション全体の説明はこれで終わりました.ここにはいくつかの小さな知識点があります.
どのように自分のプロジェクトの中でどれらのtaskがあることを知っていますか?
ASでterminalを開き、./を入力します.gradlew tasks,buildが成功するとすべてのtaskが印刷されます
Build Variantとは何ですか? Build Type + Product Flavor = Build Variant flavorはsunmi、build typeはdebug、build variantはsunmiDebug プロジェクトにflavorがあると、より多くのtaskが作成されますか?
yesは、次のように作成されます.
library publishって何ですか?
例えば次の依存
lib 1をコンパイルする場合、flavor 1 Releaseバージョンがデフォルトでパッケージされます.
他に質問があれば、交流を歓迎します.
余計なことは言わないで、本題に入って、解決策をみんなに分かち合って、友达が回り道をしないことを望んでいます.
では、いつ仲間は私が直面した問題に直面しますか?
BuildConfig.FLAVOR
でビジネスを区別する必要があります.たとえば、if (BuildConfig.FLAVOR.equals("weipos")) {
// weipos related source
} else {
//
}
現在、プロジェクトには多くのルートがありますが、ここでは主にプロジェクトに接続されているPOS機ルート-iboxpay、sunmi、weiposに注目します.私たちのビジネスコードでは、異なるflavorによって異なる機能を実現する必要があります.
メインエンジニアリングの
build.gradle
ファイルでは、以下のflavorを定義します.productFlavors {
def customFlavors = getCustomFlavors()
if (customFlavors instanceof List) {
customFlavors.each {
flavor ->
"$flavor"{
}
}
}
full {
buildConfigField"boolean","POS","false"
buildConfigField"String","DEVICE_TYPE","\"android\""
}
iboxpay {
buildConfigField"boolean","POS","true"
buildConfigField"String","DEVICE_TYPE","\"android-iboxpay\""
}
sunmi {
buildConfigField"boolean","POS","true"
buildConfigField"String","DEVICE_TYPE","\"android-sunmi\""
}
weipos {
buildConfigField"boolean","POS","true"
buildConfigField"String","DEVICE_TYPE","\"android-weipos\""
}
}
POS機業務と一般業務を区別するためには、コンパイル時に具体的なtask nameに従って区別する必要がある.例えばtaskが
assembleSumiDebug
であればgroupPosPrefixの値はSummi、buildType Prefixの値はDebugであり、groupPosPrefixの値が私が定義したflavorのIboxpay、Summi、WeiposであればgroupPosの値は「pos」であり、そうでなければ空の文字列である.注意:ここでは大文字と小文字の問題に注意し、Summiはsunmiで代用できません.
// global variables
ext{
buildType = ""
groupPos=""
}
//start parameters
println "Start parameters:tasks=" + gradle.startParameter.getTaskNames();
gradle.startParameter.getTaskNames().each { task->
def taskParts = splitCamelCase(task.split(":").last());
def groupPosPrefix = taskParts[taskParts.size() - 2];
def buildTypePrefix = taskParts[taskParts.size() - 1];
if ("Debug".startsWith(buildTypePrefix)) {
buildType = 'debug';
} else if ("Release".startsWith(buildTypePrefix)) {
buildType = 'release';
} else {
return; // do not process tasks that are not ending with proper build type.
}
if ("Iboxpay".startsWith(groupPosPrefix)) {
groupPos = 'pos';
} else if ("Sunmi".startsWith(groupPosPrefix)) {
groupPos = 'pos';
} else if ("Weipos".startsWith(groupPosPrefix)) {
groupPos = "pos"
} else {
groupPos = ""
}
}
def splitCamelCase(String word) {
def result = []
int nextStart = 0;
for (int i = 1; i < word.length(); i++) {
if(word.charAt(i).isUpperCase()) {
result.add(word.substring(nextStart, i));
nextStart = i;
}
}
result.add(word.substring(nextStart));
return result;
}
dependencies {
if (groupPos =="pos") {
iboxpayCompile project(':pos_iboxpay')
iboxpayCompile project(path:':wsc_goods',configuration:'iboxpayRelease')
sunmiCompile project(':pos_sunmi')
sunmiCompile project(path:':wsc_goods',configuration:'sunmiRelease')
weiposCompile project(':pos_wei')
weiposCompile project(path:':wsc_goods',configuration:'weiposRelease')
} else {
compile project(path:':wsc_goods',configuration:'fullRelease')
}
このように
groupPos
という変数により,一般業務とPOS業務と他のmoduleとの依存関係を自由に制御でき,一般業務とPOS機業務のコンパイル上の分離が容易に実現できる.くりを一つあげる
この例は商品moduleです.このlibraryではbuildです.gradleでもappのgradleと同じProductFlavorを定義する必要があります.
productFlavors {
full {
buildConfigField"boolean","POS","false"
buildConfigField"String","DEVICE_TYPE","\"android\""
}
iboxpay {
buildConfigField"boolean","POS","true"
buildConfigField"String","DEVICE_TYPE","\"android-iboxpay\""
}
sunmi {
buildConfigField"boolean","POS","true"
buildConfigField"String","DEVICE_TYPE","\"android-sunmi\""
}
weipos {
buildConfigField"boolean","POS","true"
buildConfigField"String","DEVICE_TYPE","\"android-weipos\""
}
}
これらのflavorを書き終わったら、
publishNonDefault true
という言葉を忘れないでください.そうしないと、対応するconfigurationが見つかりません.android {
publicNonDefault true
}
なぜcustomFlavorがないのかという仲間がいるかもしれませんが、baidu、wandoujiaなどのカスタムチャネルで使用されているビジネスコードはfullというflavorと同じなので、moduleのbuildでは再び必要ありません.gradleで定義しました.
appのbuild.gradleと商品libraryのbuild.gradleが上記のように構成されている場合、terminalで実行します./gradlew assembleDebugは、full、sunmi、iboxpay、weiposの4つのチャネルのapkをスムーズにパッケージ化できます.
まとめ
ソリューション全体の説明はこれで終わりました.ここにはいくつかの小さな知識点があります.
どのように自分のプロジェクトの中でどれらのtaskがあることを知っていますか?
ASでterminalを開き、./を入力します.gradlew tasks,buildが成功するとすべてのtaskが印刷されます
Build Variantとは何ですか?
yesは、次のように作成されます.
assemble
assemble
assemble
library publishって何ですか?
例えば次の依存
dependencies {
flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
}
lib 1をコンパイルする場合、flavor 1 Releaseバージョンがデフォルトでパッケージされます.
他に質問があれば、交流を歓迎します.