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

使用编译技巧的Android免费/付费应用程序,android,Android,我想知道您是否可以使用编译器的技巧为免费和付费版本的应用程序包含不同的函数。例如: public static final boolean paid = false; if (paid){ runPaidMethod(); } else { runFreeMethod(); } 编译器将看到这一点,并说它不需要if语句的第一个分支,因此它不会编译它。此外,它应该查看程序,发现runPaidMethod()不再从任何地方引用,并将其删除 因此,问题是:是否可以只使用此标志,免费

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

public static final boolean paid = false;

if (paid){
    runPaidMethod();
}
else {
    runFreeMethod();
}
编译器将看到这一点,并说它不需要if语句的第一个分支,因此它不会编译它。此外,它应该查看程序,发现
runPaidMethod()
不再从任何地方引用,并将其删除


因此,问题是:是否可以只使用此标志,免费编译一次,交换标志,然后重新编译以获得报酬?

您试图表达的概念称为。在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() {
   }
}

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

使用最终的布尔变量是好的,因为Java编译器足够聪明,可以看到您的条件总是错误的。如果您反编译编译后的类(您可以尝试使用
javap-c
命令),您将看到您的代码:

public static final boolean paid = false;

if (paid) {
    runPaidMethod();
}
else {
    runFreeMethod();
}
将编译为单个调用,以:

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


但是,从维护的角度来看,最好使用它来处理多个应用程序版本。

JIT处理字节码,Java编译器处理源代码。你在说什么?如果我敢打赌,我会把它翻译成“在java中实现ifdef等价物的最佳方法是什么?”:-)我猜是java编译器。我希望从免费版本中删除付费方法,以便攻击者无法反编译,将标志更改为true,然后运行付费方法。如果我错了,请更正我,但只有当变量为
final
时,这不才有效吗?我不认为静态和它有任何关系。是的,不管它是静态的还是非静态的,我只是把它加进去,因为我会用它。