使用编译技巧的Android免费/付费应用

时间:2012-06-23 17:28:30

标签: android

我想知道你是否可以使用编译器的技巧来为应用程序的免费和付费版本包含不同的功能。例如:

public static final boolean paid = false;

if (paid){
    runPaidMethod();
}
else {
    runFreeMethod();
}

编译器会查看它并说它不需要if语句的第一个分支,因此它不会编译它。此外,它应该查看该程序,并看到runPaidMethod()不再从任何地方引用并删除它。

因此问题是:只有这个标志是可行的,免费编译一次,交换标志然后再次编译为付费吗?

2 个答案:

答案 0 :(得分:2)

使用最终的布尔变量很好,因为Java编译器足够聪明,可以看到您的条件始终为false。如果您对已编译的类进行反编译(您可以使用javap -c命令进行反编译),您将看到您的代码:

public static final boolean paid = false;

if (paid) {
    runPaidMethod();
}
else {
    runFreeMethod();
}

将编译为一次调用:

runFreeMethod();

编译器删除任何无法访问的代码,因此没有人能够对您的应用进行反向工程。但要小心,您必须将runPaidMethod()声明为私有方法,否则其内容仍将出现在已编译的类中。

但从维护的角度来看,最好使用Library Projects来处理多个应用版本。

答案 1 :(得分:1)

您尝试表达的概念称为conditional compilation。在C或C ++这样的语言中,您可以通过预处理程序指令和编译器标志的组合来实现此目的。一个相当粗略的例子:

#ifdef PAID
    runPaidMethod();
#else
    runFreeMethod();
#endif

好,坏或无动于衷,Java中不存在这种条件编译。但那不是说你想要做的事情无法实现,你只需要以更加面向对象的方式思考。实现您所寻求的内容的一种方法是将主要服务提供商定义为接口,并提供付费和免费版本的实现。类似的东西:

public interface UsefulService {
    public void someMethod();
    public void otherMethod();
}

public class BaseUsefulService {
   // Common functionality here
   public void otherMethod() {
   }
}

public class FreeUsefulService {
    public void someMethod() {
    }
}

public class PaidUsefulService {
   public void someMethod() {
   }
}

通过这种细分,您实际上可以将应用程序的付费版本构建到一个完全独立的应用程序中(通过将所有服务提供程序放在一个单独的项目中)。