我的(Gradle1.10和gradle plugin 0.8)-based安卓项目由一个很大的android库组成,它依赖于3个不同的android应用。
在我的库中,我希望能够使用这样的结构
if (BuildConfig.SOME_FLAG) {
callToBigLibraries()
}
根据SOME_FLAG的最终值,as proguard将能够减小生成的apk的大小。
但我不知道如何使用gradle:
* the BuildConfig produced by the library doesn't have the same package name than the app
* I have to import the BuildConfig with the library package in the library
* The apk of an apps includes the BuildConfig with the package of the app but not the one with the package of the library.
我尝试过使用BuildTypes等工具,但没有成功
release {
// packageNameSuffix "library"
buildConfigField "boolean", "SOME_FLAG", "true"
}
debug {
//packageNameSuffix "library"
buildConfigField "boolean", "SOME_FLAG", "true"
}
为我的库和我的应用程序构建共享BuildConfig的正确方法是什么,这些应用程序的标志将在应用程序中构建时被覆盖?
发布于 2014-01-29 08:25:43
您不能随心所欲,因为BuildConfig.SOME_FLAG
不会正确地传播到您的库中;构建类型本身不会传播到库中--它们总是作为发行版构建的。这是bug https://code.google.com/p/android/issues/detail?id=52962
解决方法:如果你能控制所有的库模块,你可以确保callToBigLibraries()
接触到的所有代码都在类和包中,这样你就可以用ProGuard清晰地分离出来,然后使用反射,这样你就可以访问它们,如果它们不存在,你就可以优雅地降级。你本质上是在做同样的事情,但你是在运行时而不是编译时进行检查,这有点困难。
如果你不知道怎么做,请告诉我;如果你需要的话,我可以提供一个样本。
发布于 2014-08-12 22:34:07
作为一种解决方法,您可以使用此方法,该方法使用反射从应用程序(而不是库)获取字段值:
/**
* 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 Issue Tracker上分享了这个解决方案。
发布于 2015-07-23 20:47:23
对于applicationId与包不同的情况(即每个项目有多个applicationIds ),并且您希望从库项目访问:
使用Gradle将基础包存储在资源中。
在main/AndroidManifest.xml中:
android {
applicationId "com.company.myappbase"
// note: using ${applicationId} here will be exactly as above
// and so NOT necessarily the applicationId of the generated APK
resValue "string", "build_config_package", "${applicationId}"
}
在Java中:
public static boolean getDebug(Context context) {
Object obj = getBuildConfigValue("DEBUG", context);
if (obj instanceof Boolean) {
return (Boolean) o;
} else {
return false;
}
}
private static Object getBuildConfigValue(String fieldName, Context context) {
int resId = context.getResources().getIdentifier("build_config_package", "string", context.getPackageName());
// try/catch blah blah
Class<?> clazz = Class.forName(context.getString(resId) + ".BuildConfig");
Field field = clazz.getField(fieldName);
return field.get(null);
}
https://stackoverflow.com/questions/21365928
复制相似问题