2012-06-23 2 views
1

Мне было интересно, можете ли вы использовать трюк компилятора для включения различных функций для бесплатной и платной версии приложения. Например:Android бесплатное/платное приложение с использованием трюка компилятора

public static final boolean paid = false; 

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

компилятор будет смотреть на это и сказать, что он не нуждается в первую ветвь, если заявление, поэтому он не будет компилировать его. Кроме того, он должен посмотреть на программу и увидеть, что runPaidMethod() больше не ссылается нигде и удаляет его.

Поэтому возникает вопрос: возможно ли иметь этот флаг, скомпилировать его один раз бесплатно, обменять флаг, а затем скомпилировать его снова для оплаты?

+2

JIT работает на * bytecode *, Java-компилятор работает с * исходным кодом *. О чём вы говорите? –

+0

Если бы я сделал ставку, я бы перевел это как «лучший способ получить эквивалент ifdef в java?» :-) – davidcesarino

+0

Я думаю, что компилятор Java. Я бы хотел, чтобы платные методы удалялись из бесплатной версии, чтобы злоумышленник не мог скомпилировать, изменить флаг на true и затем запустить платные методы. –

ответ

2

Использование конечной булевой переменной хорошо, потому что компилятор Java достаточно умен, чтобы убедиться, что ваше условие всегда ложно. Если вы декомпилировать скомпилированный класс (вы можете попробовать его с помощью команды javap -c), вы увидите, что ваш код:

public static final boolean paid = false; 

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

будет составлен к одному вызову:

runFreeMethod(); 

компилятор удаляет любой недостижимый код, поэтому никто не сможет перепроектировать ваше приложение. Но будьте осторожны, вы должны объявить runPaidMethod() как частный метод, или его содержимое по-прежнему будет отображаться в скомпилированном классе.

Однако с точки зрения обслуживания все же лучше использовать Library Projects для обработки нескольких версий приложений.

+0

Исправьте меня, если я ошибаюсь, но не будет ли это работать, только если переменная 'final'? Я не думал, что статичность имеет к этому какое-то отношение. – Austin

+0

Да, это не имеет значения, статично оно или нет, я просто добавил это, потому что это то, что я буду использовать. –

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() { 
    } 
} 

С такого рода поломки вы можете построить платную версию приложения в совершенно отдельное приложение (поставив все свои поставщики услуг в отдельный проект).