请告诉我部署一个Android应用程序的若干定制版本的最好方法?
目前,我有一个脚本来交换资源文件夹,让我的应用程序的定制版本。 它的伟大工程,但所有的自定义版本仍然在AndroidManifest.xml相同的封装名称。 因此,它是不可能在同一时间安装应用两个定制版本。
这是该问题的一个解决方案,但必须由手工完成
你能想到一个更简单的解决方案,或者这到底是怎么被内置到一个skript?
(顺便说一句:这不是一个色情/垃圾邮件/任何应用程序,甚至没有一个付费)
请告诉我部署一个Android应用程序的若干定制版本的最好方法?
目前,我有一个脚本来交换资源文件夹,让我的应用程序的定制版本。 它的伟大工程,但所有的自定义版本仍然在AndroidManifest.xml相同的封装名称。 因此,它是不可能在同一时间安装应用两个定制版本。
这是该问题的一个解决方案,但必须由手工完成
你能想到一个更简单的解决方案,或者这到底是怎么被内置到一个skript?
(顺便说一句:这不是一个色情/垃圾邮件/任何应用程序,甚至没有一个付费)
也许,内置Android“库”的概念并没有完全在原来的职位时出炉,但它可能是首选的方法,在2011年按照以下步骤一个Ant构建:
从工作程序启动(姑且称之为目录“myOrigApp”,包com.foo.myapp),刚刚加入这一行“default.properties”,使之成为库:
android.library=true
现在创建在任何你喜欢的方式同级目录中创建新的应用程序(我们称之为目录“兄弟”,包com.foo.myVariant)。 使用IntelliJ IDEA的,例如,创建“从无到有”的一个项目与目录“兄弟”,它会创造一切,你通常会需要的文件/目录。
在这种新的,同级目录编辑“default.properties”添加依赖性:
android.library.reference.1=../myOrigApp
在清单复制从原来的目录:
cd sibling
cp ../myOrigApp/AndroidManifest.xml ../myOrigApp/local.properties ../myOrigApp/build.properties .
该复制清单文件,以它的包名更改为新变种,“com.foo.myVarient”编辑; 这是唯一的变化。
如果你只是运行Ant构建脚本,你可以这样做。 (我不得不刚成立签名密钥)。
如果你想建立类似想法的IDE有库项目的相关变体项目,请按照下列步骤将库项目添加到变种项目(假设你已经有一个项目设置为两者):
什么我做了一些类似的是只使用一个的antlib任务,然后再通过所有的Java和XML文件到我的老包字符串替换为新的包串。 它没有问题,如果文件根据包中的正确的SRC路径没有。 只是在做一个正则表达式替换所有文件,就足以让我得到这个工作...
例如,要在src目录下的所有Java文件替换它:
<replaceregexp flags="g" byline="false">
<regexp pattern="old.package.string" />
<substitution expression="new.package.string" />
<fileset dir="src" includes="**/*.java" />
</replaceregexp>
你一定要使用Gradle
口味自带原生,甚至鼓励,在Android工作室。
这似乎可以解释所有的基本知识真的很好。 我刚刚完成转换Gradle
的今天,它的伟大工程。 自定义的应用程序图标,名称和字符串等
由于该网站解释说,这种设计背后的目的部分是使其更具活力,更加方便的让多个APK与本质上是相同的代码,这听起来类似于你在做什么来创建。
我可能没有解释它是最好的,但该网站做了很好的工作。
链接到的解决方案不必手工完成。 请记住,在package
中的属性<manifest>
如您在清单的其他地方拼出来的完全限定类(例如,元素并不一定是在代码所在,只要activity android:name="com.commonsware.android.MyActivity"
而不是activity android:name=".MyActivity"
)。 脚本您的清单变化,使用Ant来建立一个新的APK。 据我所知,这应该工作。
支持多个合作伙伴准备的config.xml
建立不同的合作伙伴项目
<!--partner.dir, pkg.name, ver.code, ver.name are input from command line when execute 'ant' -->
<!-- set global properties for this build -->
<property name="build.bin" location="bin"/>
<property name="build.gen" location="gen"/>
<property name="src" location="src"/>
<property name="res" location="res"/>
<target name="preparefiles" description="Prepare files for different partner" >
<delete dir="${build.bin}" />
<delete dir="${build.gen}" />
<copy todir="${res}" overwrite="true" />
<fileset dir="${partner.dir}/res" />
</copy>
<!-- change the import in all Java source files -->
<replaceregexp file="AndroidManifest.xml"
match='android.versionCode="(.*)"'
replace='android.versionCode="${ver.code}"'
byline="false">
<replaceregexp file="AndroidManifest.xml"
match='android.versionName="(.*)"'
replace='android.versionName="${ver.name}"'
byline="false">
<replaceregexp file="AndroidManifest.xml"
match='package="(.*)"'
replace='package="${pkg.name}"'
byline="false">
<!-- change the package name in AndroidManifest -->
<replaceregexp flags="g" byline="false">
<regexp pattern="import(.*)com.myproject.com.R;" />
<substitution expression="import com.${pkg.name}.R;" />
<fileset dir="${src}" includes="**/*.java" />
</replaceregexp>
<replaceregexp flags="g" byline="false">
<regexp pattern="(package com.myproject.com;)" />
<substitution expression="\1 import com.${pkg.name}.R;" />
<fileset dir="${src}" includes="**/*.java" />
</replaceregexp>
</target>
准备文件$蚂蚁-f config.xml中-Dpartner.dir = “XXX” -Dpkg.name = “XXX” -Dver.code = “XXX” -Dver.name = “XXX” preparefiles
创建build.xml构建$蚂蚁调试或$发行蚂蚁
我使用Maven的Android的插件来实现这一目标。 指定一个AndroidManifest.xml中所生成的来源目标,另一个AndroidManifest.xml中为最终目标的apk。 这样的源代码项目生成R类和构建阶段的过程中保持的实际源代码包名称,而市场适于清单包名称是在其中包含在最终的apk文件的第二AndroidManifest.xml中。
我结束了与该补丁来源的脚本; 修补源的声音有风险的,但在版本控制的存在的风险是可接受的。
所以我做了一个版本,致力源,提出的其他版本,所犯下的来源,看的diff在Python写了一个补丁脚本。
我不知道这是否是最好的解决办法。 (和代码错过一些os.path.joins)
脚本的心脏是以下功能:
# In the file 'fname',
# find the text matching "before oldtext after" (all occurrences) and
# replace 'oldtext' with 'newtext' (all occurrences).
# If 'mandatory' is true, raise an exception if no replacements were made.
def fileReplace(fname,before,newtext,after,mandatory=True):
with open(fname, 'r+') as f:
read_data = f.read()
pattern = r"("+re.escape(before)+r")\w+("+re.escape(after)+r")"
replacement = r"\1"+newtext+r"\2"
new_data,replacements_made = re.subn(pattern,replacement,read_data,flags=re.MULTILINE)
if replacements_made and really:
f.seek(0)
f.truncate()
f.write(new_data)
if verbose:
print "patching ",fname," (",replacements_made," occurrence", "s" if 1!=replacements_made else "",")"
elif replacements_made:
print fname,":"
print new_data
elif mandatory:
raise Exception("cannot patch the file: "+fname)
你会发现使用下列之一:
# Change the application resource package name everywhere in the src/ tree.
# Yes, this changes the java files. We hope that if something goes wrong,
# the version control will save us.
def patchResourcePackageNameInSrc(pname):
for root, dirs, files in os.walk('src'):
if '.svn' in dirs:
dirs.remove('.svn')
for fname in files:
fileReplace(os.path.join(root,fname),"import com.xyz.",pname,".R;",mandatory=False)
还有,从副本资产的功能x-assets-cfgname
到assets
(早期事实证明,这对我来说是更方便的在子目录assets
)。
def copyAssets(vname,force=False):
assets_source = "x-assets-"+vname+"/xxx"
assets_target = "assets/xxx"
if not os.path.exists(assets_source):
raise Exception("Invalid variant name: "+vname+" (the assets directory "+assets_source+" does not exist)")
if os.path.exists(assets_target+"/.svn"):
raise Exception("The assets directory must not be under version control! "+assets_target+"/.svn exists!")
if os.path.exists(assets_target):
shutil.rmtree(assets_target)
shutil.copytree(assets_source, assets_target, ignore=shutil.ignore_patterns('.svn'))
反正你懂这个意思。 现在,您可以编写自己的脚本。
我认为最好的方法是创建一个新的项目和复制的东西。 步骤 - 无类来创建新的Android项目 - 创建包(包的名字应该是对应于一个清单文件),或者只是在“根”文件夹中复制软件包的名称 - 复制java文件 - 复制绘制文件夹 - 复制布局文件 - 复制乌尔项目中使用的任何其他文件(S) - 复制清单文件的数据
这一直是简单的,我的任务