Android的 - 同一应用程序的多个版本的定制(Android – multiple custo

2019-06-17 23:34发布

请告诉我部署一个Android应用程序的若干定制版本的最好方法?

目前,我有一个脚本来交换资源文件夹,让我的应用程序的定制版本。 它的伟大工程,但所有的自定义版本仍然在AndroidManifest.xml相同的封装名称。 因此,它是不可能在同一时间安装应用两个定制版本。

这是该问题的一个解决方案,但必须由手工完成

你能想到一个更简单的解决方案,或者这到底是怎么被内置到一个skript?

(顺便说一句:这不是一个色情/垃圾邮件/任何应用程序,甚至没有一个付费)

Answer 1:

也许,内置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有库项目的相关变体项目,请按照下列步骤将库项目添加到变种项目(假设你已经有一个项目设置为两者):

  • 打开原来的项目,带来了项目设置,选择面和检查“是图书馆计划”并保存。
  • 打开变形的项目,带来了项目设置,选择模块
  • 添加一个模块
  • 选择“导入现有的模块”
  • 浏览到原来的目录(myOrigApp)并选择其.iml文件(的IntelliJ项目源文件)
  • 点击“完成”。 (库项目被添加作为变体项目内的模块。)
  • 在模块列表中单击该项目变来选择它。
  • 在右侧选择“相关性”选项卡。
  • 点击“添加...”
  • 选择“模块的依赖......”(A列表应包括您以前添加到项目中的模块/库的名称 - 也许在列表中唯一的条目)。
  • 选择添加的库项目,然后按OK。 (它将被添加到你的项目的依赖项列表。)
  • 按OK完成配置项目。 (你应该看到2个模块,与图书馆的资源和类可用并且在变项目的认可。)


Answer 2:

什么我做了一些类似的是只使用一个的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>


Answer 3:

一定要使用Gradle口味自带原生,甚至鼓励,在Android工作室。

这似乎可以解释所有的基本知识真的很好。 我刚刚完成转换Gradle的今天,它的伟大工程。 自定义的应用程序图标,名称和字符串等

由于该网站解释说,这种设计背后的目的部分是使其更具活力,更加方便的让多个APK与本质上是相同的代码,这听起来类似于你在做什么来创建。

我可能没有解释它是最好的,但该网站做了很好的工作。



Answer 4:

链接到的解决方案不必手工完成。 请记住,在package中的属性<manifest>如您在清单的其他地方拼出来的完全限定类(例如,元素并不一定是在代码所在,只要activity android:name="com.commonsware.android.MyActivity"而不是activity android:name=".MyActivity" )。 脚本您的清单变化,使用Ant来建立一个新的APK。 据我所知,这应该工作。



Answer 5:

支持多个合作伙伴准备的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&#10;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构建$蚂蚁调试或$发行蚂蚁



Answer 6:

我使用Maven的Android的插件来实现这一目标。 指定一个AndroidManifest.xml中所生成的来源目标,另一个AndroidManifest.xml中为最终目标的apk。 这样的源代码项目生成R类和构建阶段的过程中保持的实际源代码包名称,而市场适于清单包名称是在其中包含在最终的apk文件的第二AndroidManifest.xml中。



Answer 7:

我结束了与该补丁来源的脚本; 修补源的声音有风险的,但在版本控制的存在的风险是可接受的。

所以我做了一个版本,致力源,提出的其他版本,所犯下的来源,看的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-cfgnameassets (早期事实证明,这对我来说是更方便的在子目录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'))

反正你懂这个意思。 现在,您可以编写自己的脚本。



Answer 8:

我认为最好的方法是创建一个新的项目和复制的东西。 步骤 - 无类来创建新的Android项目 - 创建包(包的名字应该是对应于一个清单文件),或者只是在“根”文件夹中复制软件包的名称 - 复制java文件 - 复制绘制文件夹 - 复制布局文件 - 复制乌尔项目中使用的任何其他文件(S) - 复制清单文件的数据

这一直是简单的,我的任务



文章来源: Android – multiple custom versions of the same app