基于一个代码库/项目创建演示和完整版应用程序

时间:2012-10-18 20:41:18

标签: android build android-library conditional-compilation

我在Eclipse的一个项目中开发了一个Android应用程序 - 它是结构化的(来自iPhone),所以一个常量定义它是演示版还是完整版。

现在我遇到的问题是每次我想要创建演示版本时我需要更改常量,但还需要使用不同的包名创建项目的副本。

显然,原始完整版中的代码更改需要复制到演示中,否则我每次提交应用时都必须重做演示应用的创建。

我看到了三种可能的方法:

1。 虽然我已经查看了图书馆项目,但我仍然不清楚这在这种情况下如何真正提供一个好的解决方案。

例如,如果我有完整版本的活动结构:

A1
A2
A3

使用实用程序类U1,U2

当然U1和U2可以在一个库项目中并从两个项目中引用 - 但是活动,strings.xml,图形,布局需要重复(或者是否有另一种我看不到的方式?)这样做这似乎不是一个很好的前进方式,不幸的是,当提出这种方法时,在这个主题的类似问题中没有解释过。

2。 另一种方法是根据不同的构建设置(类似于iPhone)创建不同的包名称,但是,这似乎不可能在Eclipse中使用而不是使用一些外部脚本(诚实地说 - 我宁愿避免,因为它似乎相当容易出错)同时还必须在Eclipse外部调用编译

3。 可能最直接的方法(目前还有很少的努力)只是手动复制项目,更改一个常量,重命名包并在每次提交时编译/导出。然而 - 这似乎是相当“基本的”,当然看起来并不专业(与iPhone / xCode构建设置/目标解决方案相比)

什么是最好的方法(需要最少量的更改并且仍然稳定且易于使用)?

非常感谢!

修改

对于尝试过蒂姆解决方案的每个人 - 它运行正常,但是我遇到了自定义属性的问题。

检查一下:How to solve Android Libraries custom attributes and package name remapping during build? 它将解决图书馆的问题

3 个答案:

答案 0 :(得分:8)

我目前在日食中这样做,并不难。

  1. 将现有资源转换为图书馆计划。

  2. 创建两个免费和付费的新项目。

  3. 将库项目包含在免费和付费项目中。

  4. 免费/付费项目中没有必要拥有一个活动或资源。您需要的只是每个表明您的图书馆活动的清单。我的免费和完整项目目前没有任何类型的java,资源或布局文件,它只是一个引用库中活动的清单。

    我对两个项目使用完全相同的代码,我通过说:

    来区分它们
    if(getApplicationContext().getPackageName().equals("full version package name")) {
        //do full stuff
    } else {
        //do free stuff
    }
    

    我遇到了一些问题,特别是如果你已经在市场上发布了应用程序:

    • 如果您更改任何活动的全名/路径,它将从您的主屏幕中消失。因此,如果您的库具有与现有版本不同的包名,您将丢失所有主屏幕图标。它们可以由用户替换,但它并不理想。
    • 类似于appwidgets,如果您更改其接收者名称,它们将在升级时消失。
    • 在任何情况下,您都不得更改已发布应用程序的包名称。

    如果您已经发布了免费版和专业版,那有点不幸,因为活动路径需要更改为公共库路径,并且您无法重命名已发布的包以匹配库路径。所以有人将失去现有的图标。

    在我的情况下,我在分割它们之前只发布了一个免费版本,并且我能够使用相同的包名称命名该库作为免费版本。我怀疑你是否被允许包含一个与包装包具有相同包装名称的库,但显然它可以这样做(对我来说工作正常)。

    所以在我的情况下,我有三个项目:

    • 核心库:包名:com.myname.myapp
    • 免费版:包名:com.myname.myapp
    • 专业版:包名:com.myname.myapp.Pro

    免费版和完整版显示添加名为com.myname.myapp.ActivityAcom.myname.myapp.ActivityB的活动,这些活动仅存在于库项目中。

答案 1 :(得分:2)

我认为最简单的方法是有三个项目:

  1. 演示
  2. 文库
  3. 演示和完整项目将各自具有其各自的Manifest文件中定义的唯一包名称。他们的活动只是将包中的信息发送到库项目中的主要活动的端口。库项目中的Activity将读取传入的Bundle,以获取必要的参数,以确定它是由演示Activity还是完整的Activity启动的。然后它会相应地进行。

    所以逻辑是这样的:

    用户启动演示活动 - >演示活动创建了一个Bundle,其中包含的信息表明它是演示活动 - >演示Activity启动库Activity,然后以演示模式执行程序的其余部分。

    OR

    用户启动完整的活动 - >完整的Activity创建一个Bundle,其中包含的信息表明它是完整的Activity - >完整的Activity启动库Activity,然后以完整模式执行程序的其余部分。

答案 2 :(得分:1)

在Android Studio中使用build.gradle非常简单。阅读productFlavors。这是一个非常有用的功能。只需在build.gradle中添加以下行:

productFlavors {
    lite {
        packageName = 'com.project.test.app'
        versionCode 1
        versionName '1.0.0'
    }
    pro {
        packageName = 'com.project.testpro.app'
        versionCode 1
        versionName '1.0.0'
    }
}

在这个例子中,我添加了两种产品口味:第一种用于精简版,第二种用于完整版。每个版本都有自己的versionCode和versionName(适用于Google Play出版物)。

在代码中只需检查BuildConfig.FLAVOR:

if (BuildConfig.FLAVOR == "lite") {
   // add some ads or restrict functionallity

}

要在设备上运行和测试,请使用Android Studio中的“Build Variants”选项卡在版本之间切换: enter image description here