首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Gradle :如何在android库中使用在应用程序中设置标志的BuildConfig

Gradle :如何在android库中使用在应用程序中设置标志的BuildConfig
EN

Stack Overflow用户
提问于 2014-01-27 00:17:13
回答 4查看 46K关注 0票数 61

我的(Gradle1.10和gradle plugin 0.8)-based安卓项目由一个很大的android库组成,它依赖于3个不同的android应用。

在我的库中,我希望能够使用这样的结构

代码语言:javascript
复制
if (BuildConfig.SOME_FLAG) {
    callToBigLibraries()
}

根据SOME_FLAG的最终值,as proguard将能够减小生成的apk的大小。

但我不知道如何使用gradle:

代码语言:javascript
复制
* 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等工具,但没有成功

代码语言:javascript
复制
release {
    // packageNameSuffix "library"
    buildConfigField "boolean", "SOME_FLAG", "true"
}
debug {
    //packageNameSuffix "library"
    buildConfigField "boolean", "SOME_FLAG", "true"
}

为我的库和我的应用程序构建共享BuildConfig的正确方法是什么,这些应用程序的标志将在应用程序中构建时被覆盖?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-01-29 08:25:43

您不能随心所欲,因为BuildConfig.SOME_FLAG不会正确地传播到您的库中;构建类型本身不会传播到库中--它们总是作为发行版构建的。这是bug https://code.google.com/p/android/issues/detail?id=52962

解决方法:如果你能控制所有的库模块,你可以确保callToBigLibraries()接触到的所有代码都在类和包中,这样你就可以用ProGuard清晰地分离出来,然后使用反射,这样你就可以访问它们,如果它们不存在,你就可以优雅地降级。你本质上是在做同样的事情,但你是在运行时而不是编译时进行检查,这有点困难。

如果你不知道怎么做,请告诉我;如果你需要的话,我可以提供一个样本。

票数 22
EN

Stack Overflow用户

发布于 2014-08-12 22:34:07

作为一种解决方法,您可以使用此方法,该方法使用反射从应用程序(而不是库)获取字段值:

代码语言:javascript
复制
/**
 * 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调用它

代码语言:javascript
复制
boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG");

我也在AOSP Issue Tracker上分享了这个解决方案。

票数 49
EN

Stack Overflow用户

发布于 2015-07-23 20:47:23

对于applicationId与包不同的情况(即每个项目有多个applicationIds ),并且您希望从库项目访问:

使用Gradle将基础包存储在资源中。

在main/AndroidManifest.xml中:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
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);
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21365928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档