Создание нескольких (тестовых/prod) версий Android APK в Eclipse
Я ищу оптимизацию создания немного разных APK одного и того же приложения для Android, с той лишь разницей, что он использует сервер http-API (dev/staging/prod).
В идеале я просто хочу, чтобы мой Eclipse создавал 2 APK, один с сервером prod и один с dev.
Я даже в порядке с конфигурацией 2 Run, но мне не удалось выяснить, как передать параметры в приложение и прочитать их из кода.
Я хочу настроить таргетинг на 1.5, BTW, и я бы хотел использовать инструменты автоматической сборки Eclipse, поэтому я ищу наиболее общее решение.
Спасибо.
Ответы
Ответ 1
Я думаю, что использование ant build script было бы самым простым решением. Eclipse поддерживает ant build, поэтому вы можете запускать команду ant в eclipse.
Вы можете решить свою проблему с помощью ant, как это.
- подготовьте два файла ресурсов xml android.
- создать пакет с ресурсом # 1
- перезаписать ресурС# 1 с содержимым ресурса # 2
- создать другой пакет
xml будет выглядеть следующим образом:
ресурС# 1:
<resources>
<string name="target">dev</string>
</resources>
ресурС# 2:
<resources>
<string name="target">staging</string>
</resources>
и ant script будет выглядеть следующим образом:
<project>
<target name="build_all">
<copy file="res1.xml" to="res/values/target.xml"/>
<ant antfile="build.xml" target="debug"/>
<copy file="res2.xml" to="res/values/target.xml"/>
<ant antfile="build.xml" target="debug"/>
</target>
</project>
Ответ 2
Переместите весь код в проект библиотеки.
http://developer.android.com/guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject
Затем создайте отдельные проекты в eclipse для тестирования и производства с уникальным именем пакета. Затем вы можете использовать имя пакета для различения версий.
Что-то вроде:
public static boolean isProductionVersion(){
return context.getPackageName().toLowerCase().contains("production");
}
Это может показаться излишним для управления различными конечными точками http, но это сделает код более управляемым. Вы также можете делать полезные вещи, например:
- флаг тестовой версии с другим значком приложения
- запускать тестовые и производственные версии бок о бок на одном устройстве.
Это можно сделать в eclipse без использования и сторонних инструментов.
Ответ 3
Это не то, что вы хотите:
private static Boolean isSignedWithDebugKey = null;
protected boolean signedWithDebug() {
if(isSignedWithDebugKey == null) {
PackageManager pm = getPackageManager();
try {
PackageInfo pi = pm.getPackageInfo(getPackageName(), 0);
isSignedWithDebugKey = (pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
}
catch(NameNotFoundException nnfe) {
nnfe.printStackTrace();
isSignedWithDebugKey = false;
}
}
return isSignedWithDebugKey;
}
Затем вы можете попасть на сервер dev/staging, если приложение подписано с помощью отладочного ключа, и выпуск с сертификатом выпуска.
Ответ 4
Для передачи параметров вы всегда можете создать файл в системе каталогов Android и прочитать его код.
Ответ 5
В моем случае я просто хотел изменить несколько значений в strings.xml
между разными версиями.
Сначала мне нужно загрузить библиотеку ant-contrib
, чтобы определить задачу цикла for
:
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="lib/ant-contrib-1.0b5-SNAPSHOT.jar" />
</classpath>
</taskdef>
Я разместил список конфигураций config.names
в файле properties
:
config.url.root=http://projectserver.aptivate.org/
config.names=student-production, teacher-production, student-testing, teacher-testing
И определите цель build-all
, которая пересекает config.names
:
<target name="build-all">
<for param="config.name" trim="true" list="${config.names}">
<sequential>
Определение настраиваемого каталога resources
для каждого из них, сохранение имени каталога в свойстве config.resources
:
<var name="config.resources" unset="true" />
<property name="config.resources" value="bin/res-generated/@{config.name}" />
Удалите его и скопируйте в него глобальные ресурсы res
:
<delete dir="${config.resources}" />
<copy todir="${config.resources}">
<fileset dir="res"/>
</copy>
Измените -
на /
в имени конфигурации, чтобы сделать его путь в параметре URL:
<var name="config.path" unset="true" />
<propertyregex property="config.path"
input="@{config.name}" regexp="-"
replace="/" casesensitive="true" />
Запустите преобразование XSLT, чтобы изменить файл strings.xml
:
<xslt in="res/values/strings.xml"
out="${config.resources}/values/strings.xml"
style="ant/create_xml_configs.xslt"
force="true">
<param name="config.url.root" expression="${config.url.root}" />
<param name="config.name" expression="@{config.name}" />
<param name="config.path" expression="${config.path}" />
</xslt>
Это таблица стилей XSLT, которую я использую:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="config.url.root" />
<xsl:param name="config.name" />
<xsl:param name="config.path" />
<!-- http://my.safaribooksonline.com/book/xml/9780596527211/creating-output/xslt-id-4.6 -->
<xsl:template match="/">
<!--
This file is automatically generated from res/values/strings.xml
by ant/custom_rules.xml using ant/create_xml_configs.xslt.
Do not modify it by hand; your changes will be overwritten.
-->
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:copy/>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<!-- the value of update_server_url must end with a slash! -->
<xsl:template match="string[@name='update_server_url']/text()">
<xsl:value-of select="$config.url.root" /><xsl:value-of select="$config.path" />/
</xsl:template>
<xsl:template match="string[@name='app_version']/text()">
<xsl:value-of select="." />-<xsl:value-of select="$config.name" />
</xsl:template>
</xsl:stylesheet>
И вернемся к custom_rules.xml
, где затем извлеките app_version
из исходного (немодифицированного) res/values/strings.xml
:
<xpath input="res/values/strings.xml"
expression="/resources/string[@name='app_version']"
output="resources.strings.app_version" />
И используйте задачу antcall
для вызова debug
build:
<antcall target="debug">
<param name="resource.absolute.dir" value="${config.resources}" />
<param name="out.final.file" value="${out.absolute.dir}/${ant.project.name}-${resources.strings.app_version}[email protected]{config.name}.apk" />
</antcall>
с двумя измененными значениями свойств:
-
resource.absolute.dir
сообщает целевому устройству debug
использовать мой измененный каталог res
, определенный в свойстве config.resources
выше;
-
out.final.file
сообщает, что он создает APK с другим именем, включая имя конфигурации (например, student-testing
) и номер версии, извлеченный из strings.xml
.
И, наконец, я могу запустить ant build-all
из командной строки и собрать все четыре цели. Немного больше script, как раз перед концом цели build-all
перечисляет скомпилированные файлы APK для ссылки:
<echo message="Output packages:" />
<for param="config.name" trim="true" list="${config.names}">
<sequential>
<echo message="${out.absolute.dir}/${ant.project.name}-${resources.strings.app_version}[email protected]{config.name}.apk" />
</sequential>
</for>