Лучшая практика для доступа к свойствам gradle, специфичным для buildVariant (например, примечаниям к выпуску) из библиотечных модулей

Project имеет два варианта продукта, каждый с другим идентификатором приложения (также отличным от пакета, указанного в базовом манифесте).

Стандартно этот пакет используется для класса BuildConfig, класса R и т. д.

Каков наилучший способ программно узнать это имя пакета (не applicationId) из модулей библиотеки?

Я могу придумать несколько запутанных обходных путей, таких как сохранение его в ресурсе или СНОВА в базовом манифесте с использованием элемента метаданных:

<manifest package="com.company.myappbase">...
    <meta-data android:name="BUILD_CONFIG_PACKAGE" android:value="com.company.myappbase" />...

и поэтому к нему можно получить доступ в библиотеке с помощью контекста.

Есть ли правильный способ сделать это?

Моя мотивация заключается в том, что я хочу, чтобы библиотечный модуль имел программный доступ к свойствам, специфичным для buildVariant (например, примечаниям к выпуску, цели Appstore), определенным в build.gradle.


person Mark    schedule 22.07.2015    source источник


Ответы (3)


Если базовый пакет уже определен в build.gradle, вы можете использовать его:

android {
    applicationId "com.company.myappbase"
    // note: using ${applicationId} here will be exactly as above
    // and so NOT necessarily the applicationId of the generated APK
    manifestPlaceholders += [buildConfigPackage: "${applicationId}"]
}

Если нет (возможно, потому что вы не хотите, чтобы имя пакета определялось дважды: в build.gradle и main/AndroidManifest.xml), вы можете прочитать пакет из manfiest:

android {
    defaultConfig {
        manifestPlaceholders += [buildConfigPackage: "${readBuildConfigPackage()}"]
        ...
    }
}
def readBuildConfigPackage() {
    def manifestFile = file(project.projectDir.absolutePath + '/src/main/AndroidManifest.xml')
    def xml = new XmlParser().parse(manifestFile)
    return xml.attributes()["package"].toString()
}

HT: http://toastdroid.com/2014/03/28/customizing-your-build-with-gradle/

В main/AndroidManifest.xml:

<application ... >
    <meta-data android:name="BUILD_CONFIG_PACKAGE" android:value="${buildConfigPackage}" />

В Java:

ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
String buildConfigPackage = (String)appInfo.metaData.get("BUILD_CONFIG_PACKAGE");
person Mark    schedule 22.07.2015

Мой другой ответ работает, но сохранение имени пакета в метаданных манифеста кажется довольно хакерским.

Другое решение (также хакерское, но, может быть, чуть менее) — использовать ресурсы Android:

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}"
}

HT: https://stackoverflow.com/a/28741526/444761

В Java:

int resId = context.getResources().getIdentifier("build_config_package", "string", context.getPackageName());
String buildConfigPackage = context.getString(resId);
person Mark    schedule 23.07.2015

Так просто как

applicationId "com.foo.bar"
buildConfigField "String", "PACKAGENAME", "\"" + "${applicationId}" + "\"" 

Используйте это как

BuildConfig.PACKAGENAME
person M. Reza Nasirloo    schedule 15.08.2015
comment
Нет смысла помещать имя пакета в BuildConfig, потому что это уже доступно с BuildConfig.class.getPackage() - person Mark; 15.08.2015
comment
@MarkCarter Да, не знал об этом. - person M. Reza Nasirloo; 15.08.2015