维护应用程序的免费和专业版本

20

我想为Android创建我的应用程序的PRO版本,想知道如何构建我的存储库。

目前我有主干和功能分支。 我想把专业版放在另一个分支中,但也许还有更好的方法? 比如,也许我应该创建两个分支 - 一个免费版本,另一个专业版?

专业版将具有附加功能,并且不会显示广告,因此例如,我不想在专业版中包含AdMob库。

在这种情况下,您有任何经验或建议,可以对存储库进行最佳结构吗?

编辑: 我认为我在这个主题中找到了最好的解决方案(适用于我的应用程序): http://groups.google.com/group/android-developers/browse_thread/thread/4ad3d67f735f16d7/948b4f9eee2490a3

讨论的技巧是拥有另一个应用程序,仅用于在实际应用程序中解锁PRO功能。 解锁应用在市场上是付费的,而实际应用程序仅检查其是否存在于设备上。


3
如果用户只安装了付费的“解锁器”应用程序并期望它能够起作用,那么用户会感到困惑吗? - eigenein
5个回答

15

我知道你已经作出了决定,但我有一个建议可以帮助其他人。

我使用 git 作为我的代码库。创建和维护分支非常容易。我有我的主要“pro”代码库和一个“free”分支。我对主分支进行所有代码更改。我的“free”分支只是因为任何触发“free”行为的更改而不同。 每当我完成对代码的更改后,我会将其提交到主分支,然后切换到 free 分支,并使用“rebase”命令使其与主分支保持同步。

它会回滚使其表现为“free”版本的更改,应用我在主分支上进行的更改,然后重新应用“free”更改。

我不需要维护两个版本。我不必记住切换某个开关或来回进行相同的更改。这很方便,我比第二个应用程序更喜欢它,后者会触发 pro 行为,因为我可以剥离不适用于相应版本的库。


我自己没有想到这一点(我是Subversion用户,现在开始在svn存储库中使用git)。感谢您的提示,我会自己尝试一下(虽然我可能需要建立一个真正的git存储库服务器(我想要那些备份)...)... - MrSnowflake
我被“它回滚...”这段话搞糊涂了,这是由rebase完成的吗?还是你需要做些什么? - Francisco Corrales Morales
这一切都是作为rebase的一部分发生的。 - BenTobin
1
虽然这种方法对于一个人的开发团队可能是可行的,但对于共享存储库来说并不适用。重复的变基会改变历史记录,因此您必须强制推送到共享存储库,并确保所有克隆的共享存储库都跟随,而这实际上几乎是不可能的。 - bassim
你说得很有道理,而且我现在可能不会做出同样的建议。 - BenTobin

11

我建议不要维护两个分支,而是使用运行时或编译时开关来禁用免费版本中的PRO功能。您甚至可以在构建时删除不必要的DLL文件。

维护两个分支意味着要在两个地方修复问题,随着分支不可避免地分歧,这将成为更大的问题。


听起来很合理。我还发现一个建议,提供一个“解锁器”应用程序,需要付费,只需在设备上安装即可使用专业功能。 - Marek Stój
@Immortal 这就是Touiteur所做的事情,虽然我不知道它是如何实现的,但它很简单而且不会打扰。 - Josh Lee
@illojal 我已更新问题,包括“解锁应用程序”方法的信息。 - Marek Stój
我该如何为 .xml 文件创建一个开关?你所说的“编译时开关”是什么意思? - Francisco Corrales Morales
@FranciscoCorralesMorales - 你可能想在快速搜索后将这些问题作为进一步的问题提出。在评论中无法涵盖太多内容。 - Paddy
显示剩余2条评论

7
我在eclipse中找到了一个简单的方法。一旦我发现这个方法,我很惊讶它是多么容易。
  1. 在com.app.free项目的项目属性中,将“Is Library”设置为true(在更改此设置之前,必须至少编译一次该项目,否则您会收到错误消息,提示库项目无法编译。如果出现此错误,请取消勾选,编译,然后重新勾选)。
  2. 创建新项目com.app.pro
  3. 在pro项目的Android部分的项目设置中将com.app.free项目作为库添加进去
  4. 在com.app.pro中创建新类MyApplication并扩展Application
  5. 重写onCreate() 注意:对于那些复制/粘贴的同志们来说,这与activity的onCreate(Bundle savedInstanceState) bundle不同。因为这是一个应用程序而不是一个活动,所以必须删除Bundle参数。
  6. 然后添加或设置静态变量,该变量将在验证许可证的验证方法中读取。例如:IS_PRO = true; 然后验证方法读取变量,如果IS_PRO为真,则返回true。
  7. 将com.app.free的清单内容复制到com.app.pro中
  8. 在com.app.pro清单文件中的application标记中添加android:name="MyApplication"
  9. 在所有活动的名称属性前面附加com.app.free。(这使应用程序知道您的活动可以在库包中找到,这是免费版本)例如:android:name=".MainActivity" => android:name="com.app.free.MainActivity"
  10. 现在编译,你就有了一个专业版

该方法假定您正在使用全局验证方法。例如,我创建了一个类,将用户连接到我的域上托管的数据库,从而确定用户何时首次安装了应用程序。对于任何仅供专业使用的活动,我检查LicenseClass.isValidLicense(),它会比较日期,如果时间少于所需天数,则返回true。在isValidLicense()函数中,我检查Application.IS_PRO是否设置为true,并且如果是,则返回true。

因此,现在您可以随意更改,只需重新编译即可。唯一需要注意的是,无论您在com.app.free清单文件中进行了哪些更改,都必须在pro中进行反映。但是这适用于任何应用程序,因为Android应用程序要求您声明您将使用哪些活动。

注意:您可以删除在项目创建时自动生成的所有资产和资源(不要删除res文件夹本身),因为它们不会被使用。此外,唯一需要的类文件是第3步中的MyApplication文件。这意味着您还可以删除自动生成的MainActivity.class文件,因为它也永远不会被使用。您还可以删除未在专业版中使用的任何标记。例如:我有一个BuyPro活动,如果验证失败,则会打开它。由于专业版永远不会失败,所以不需要它。当然,所有这些删除都是可选的,只是让您知道我的经验。

CONS: 我目前发现唯一的缺点是您无法使用switch语句来处理资源变量,因为它们不再是常量。因此,当您将项目用作库时,例如在strings.xml文件中创建任何变量时,如果您在专业版中声明了同名变量,则会自动覆盖。对我来说,这不是一个缺点,因为我不喜欢在Java中使用switch语句,因为它们限制您仅在int类型上进行切换,并且需要常量值。这意味着在Java中,我通常必须使用if ... else语句。此外,Eclipse实际上将帮助您转换switch语句,如果您将光标放在switch关键字上并按Ctrl + 1,然后单击转换为if else。另外,我发现资源被覆盖非常有用,因为您可以通过在免费应用程序中存在的位置创建新版本来更改app_name从“app free”到“app pro”,或者上传新的drawable,比如应用程序图标。例如:如果res / values / string.xml包含100个字符串变量,但在专业版中您只需要或想要更改app_name,只需重新创建res / values / string.xml(而不是复制),并添加app_name变量。现在,免费版本中的app_name变量将被覆盖,这意味着专业版中的string.xml文件仅需要包含1个变量,因为它是唯一更改的变量。易如反掌。 :-)
编辑:我发现Eclipse不允许您为库导出.apk文件,因此在将其添加为专业版库之后,您必须取消选择免费版本中的“Is Library”选项。据我所知,除了导致Eclipse不警告您有关switch语句问题之外,这似乎完全正常。

这个回答需要更多的喜爱。+1 - CjS

1

有一个单一版本,其中public static final boolean IS_PRO会确定免费/专业版的行为。

编辑:
软件包问题。假设,您所有的类都在com.myapp.android.free下。
然后,在AndroidManifest.xml中,您声明package="com.myapp.android"为付费版本,package="com.myapp.android.free"为免费版本。
如果对于活动、服务等使用全名,则不需要更改其他任何内容。

我不会费心从付费版本中删除未使用的libs。如果这样做,您将不得不手动完成此操作。


1
是啊,好像我没有想到那个:/ 那在Android市场上发布应用程序怎么样?包必须是唯一的。那在专业版中不包括AdMob jar呢? - Marek Stój
谢谢你的回答。我想我会选择“解锁应用程序”的方法。 - Marek Stój
2
问题在于包名不仅在清单文件中使用,而且还用于所有引用 R.java 类的 Java 代码中(通常是很多类)。 - Cristian
我该如何对 .xml 文件进行操作? - Francisco Corrales Morales

0

我认为最好的方法是使用产品风味/构建变体。请参阅文档,以及这个示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接