[英]Build variants in Gradle for a Library Project in Android
我正在嘗試使用Gradle配置一個包含一些外部庫的項目。 使用Gradle我可以使用Build Variants為主應用程序設置不同的環境配置(在配置文件中有一個類),這樣我就可以根據這些變量執行代碼。
問題是我如何為圖書館項目做同樣的事情? 我為這個項目創建了這個庫,我想為不同的場景設置不同的Build Variants。
例如:在庫中,當在調試模式下運行時,然后打印所有日志,以便我可以在開發時看到它們。 在發布模式下不要。
文件結構:
src ----- > debug -> java -> config -> PlayerEnvConfig
main -> com.mypackagename -> etc...
release -> java -> config -> PlayerEnvConfig
debug中的代碼:package config;
/**
* Environment configuration for Release
*/
public final class PlayerEnvConfig {
public static final boolean USE_REPORTING = true;
public static final boolean USE_ANALYTICS = true;
public static final boolean USE_LOGGING = false;
public static final boolean USE_DEBUG_LOGGING = false;
public static final boolean USE_DEBUGING = false;
}
發布代碼:
package config;
/**
* Environment configuration for Release
*/
public final class PlayerEnvConfig {
public static final boolean USE_REPORTING = true;
public static final boolean USE_ANALYTICS = true;
public static final boolean USE_LOGGING = false;
public static final boolean USE_DEBUG_LOGGING = false;
public static final boolean USE_DEBUGING = false;
}
問題是,對於主項目,我可以使用此Build類型為不同場景配置不同的應用程序,但我如何為庫項目執行相同操作?
因為目前我在http://tools.android.com/tech-docs/new-build-system/user-guide中讀到的內容,庫只會在測試時使用調試模式。
有任何想法嗎?
謝謝!
這是來自谷歌代碼問題的@bifmadei答案,它對我有幫助:
嘗試在依賴項目中設置它
android {
publishNonDefault true
...
}
這在使用它的項目中
dependencies {
releaseCompile project(path: ':theotherproject', configuration: 'release')
debugCompile project(path: ':theotherproject', configuration: 'debug')
}
摘自此處: https : //code.google.com/p/android/issues/detail? id = 66805
不確定您的配置有什么問題,但有關您的需求,我會采用不同的方式。
在gradle構建文件中,您可以使用buildConfig
關鍵字將特定行添加到BuildConfig.java
生成的類中。
所以你可以在build.gradle
添加類似的東西:
release {
buildConfig "public static final String USE_REPORTING = true;"
}
debug {
buildConfig "public static final String USE_REPORTING = false;"
}
所以只有一個PlayerEnvConfig
public static final boolean USE_REPORTING = BuildConfig.USE_REPORTING;
甚至沒有更多的PlayerEnvConfig
並直接使用BuildConfig
類。
編輯自更新以來,語法已更改:
buildConfigField "<type>", "<name>", "<value>"
這在https://code.google.com/p/android/issues/detail?id=52962中有記錄。 正如您所知,構建類型不會傳播到庫項目,並且沒有一個好的解決方法。 如果您可以控制庫項目的代碼,則可以將調試狀態設置為可變全局變量,並在啟動時從主應用程序設置它。 這有點像黑客,它的缺點是編譯器無法優化未使用的代碼路徑遠離發布版本,但除非發生異常,否則它應該有效。
更新 - 自發布之日起,gradle構建過程取得了很大進展,因此這個答案可能不是推薦的最佳實踐,新的更改甚至可能會使其失效。 自行決定。
我認為整個項目結構和配置存在一些混亂。 假設您有以下build.gradle配置
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java']
//resources.srcDirs = ['src/main']
//aidl.srcDirs = ['src/main']
//renderscript.srcDirs = ['src/main']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
}
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
您的項目文件夾結構應如下所示
project_root
-src
-main
-java
-com
-example
-build-types
-debug
-java
-com
-example
-FooBar.java
-release
-java
-com
-example
-FooBar.java
FooBar.java
不能在prooject_root/src/main/java/com/example
。 它必須位於debug
和release
文件夾中,該文件夾位於src
文件夾之外但位於build-types
文件夾中。 這是由setRoot('build-types/*****')
方法配置的。 很多人因為看到'debug / java'和'main / java'而感到困惑,后者在演示中以'src / main / java'的方式引用,最后在src中放入'debug / java',錯文件夾。 我希望這有幫助。
對於涉及其他庫的更復雜的環境,您可以在這里查看我的答案https://stackoverflow.com/a/19918834/319058
對於您自己提到的庫項目,這是不可能的。
您可以將庫項目更改為應用程序項目。 這似乎工作正常(至少在理論上,我自己沒有測試過)。
另一種方法是在應用程序項目中覆蓋該類。 合並發生時將選擇您的應用程序項目類,並且您將獲得這些值。
斯科特指出,這是Gradle的一個眾所周知的缺點。 作為一種變通方法,您可以使用此方法,該方法使用反射從應用程序(而不是庫)獲取字段值:
/**
* Gets a field from the project's BuildConfig. This is useful when, for example, flavors
* are used at the project level to set custom fields.
* @param context Used to find the correct file
* @param fieldName The name of the field-to-access
* @return The value of the field, or {@code null} if the field is not found.
*/
public static Object getBuildConfigValue(Context context, String fieldName) {
try {
Class<?> clazz = Class.forName(context.getPackageName() + ".BuildConfig");
Field field = clazz.getField(fieldName);
return field.get(null);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
例如,要獲取DEBUG
字段,只需從您的Activity
調用:
boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG");
我也在AOSP問題跟蹤器上分享了這個解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.