Платное и бесплатное приложение для Android с использованием трюка с компилятором

1

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

public static final boolean paid = false;

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

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

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

  • 2
    JIT работает с байт-кодом , компилятор Java работает с исходным кодом . О чем ты говоришь?
  • 0
    Если бы я держал пари, я бы перевел это как «каков наилучший способ достичь эквивалента ifdef в java?» :-)
Показать ещё 1 комментарий
Теги:

2 ответа

2
Лучший ответ

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

public static final boolean paid = false;

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

будут скомпилированы для одного вызова:

runFreeMethod();

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

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

  • 0
    Поправьте меня, если я ошибаюсь, но не будет ли это работать, только если переменная является final ? Я не думал, что у static есть какое-то отношение к этому.
  • 0
    Да, это не должно иметь значения, статично это или нет, я просто добавил это, потому что это то, что я бы использовал.
1

Концепция, которую вы пытаетесь выразить, называется условной компиляцией. На языке, таком как 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() {
   }
}

При таком разбиении вы можете фактически создать платную версию приложения в совершенно отдельное приложение (поставив всех своих поставщиков услуг в отдельный проект).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню