Как использовать поддержку Android typedef аннотации в kotlin?

Я разрабатываю приложения для Android и часто использую аннотации для проверки параметров времени компиляции, в основном аннотации поддержки Android.

Пример в коде Java:

public class Test
{
    @IntDef({Speed.SLOW,Speed.NORMAL,Speed.FAST})
    public @interface Speed
    {
         public static final int SLOW = 0;
         public static final int NORMAL = 1;
         public static final int FAST = 2;
    }

    @Speed
    private int speed;

    public void setSpeed(@Speed int speed)
    {
        this.speed = speed;
    }
}

Я не хочу использовать перечисления из-за проблем с производительностью в Android. Автоматический конвертер в kotlin просто генерирует неверный код. Как я могу использовать @IntDef аннотация в котлине?

4 ответа

Решение

На самом деле можно использовать @IntDef поддержка аннотаций путем определения значений вне класса аннотаций как const vals.

Используя ваш пример:

import android.support.annotation.IntDef

public class Test {

    companion object {

         @IntDef(SLOW, NORMAL, FAST)
         @Retention(AnnotationRetention.SOURCE)
         annotation class Speed

         const val SLOW = 0L
         const val NORMAL = 1L
         const val FAST = 2L
    }

    @Speed
    private lateinit var speed: Long

    public fun setSpeed(@Speed speed: Long) {
        this.speed = speed
    }
}

Обратите внимание, что на данный момент компилятор, кажется, требует Long тип для @IntDef аннотация вместо фактической Ints.

В настоящее время нет способа достичь именно этого в Kotlin, так как класс аннотации не может иметь тела, и поэтому вы не можете объявить в нем константу, которая будет обработана IntDef, Я создал проблему в трекере: https://youtrack.jetbrains.com/issue/KT-11392

Для вашей проблемы, однако, я рекомендую вам использовать простой enum.

Просто создайте класс @IntDef как класс Java и получите к нему доступ через код kotlin.

Пример:

1) Создайте свой класс типов:

public class mType {
    @IntDef({typeImpl.type1, typeImpl.type2, typeImpl.type3})
    @Retention(RetentionPolicy.SOURCE)
    public @interface typeImpl {
        int type1 = 0;
        int type2 = 1;
        int type3 = 2;
    }
}

2) Поместите эту функцию в любой объект Kotlin:

object MyObject{
    fun accessType(@mType.typeImpl mType: Int) {
       ...
    }
}

3) затем получить доступ к нему:

fun somOtherFunc(){ 
        MyObject.accessType(type1)
 }

** Обратите внимание: вам не нужно помещать метод доступа внутри объекта.

Использовать этот:

companion object {
    const val FLAG_PAGE_PROCESS = 0L//待处理
    const val FLAG_PAGE_EXCEPTION = 1L//设备异常
    const val FLAG_PAGE_UNCHECKED = 2L//未审核
    const val FLAG_PAGE_AUDIT = 3L//统计
    val FLAG_PAGE = "FLAG_PAGE"

    fun newInstance(@FlagPageDef flagPage: Int): RepairFormsListFragment {
        val fragment = RepairFormsListFragment()
        val args = Bundle()
        fragment.arguments = args
        return fragment
    }

    @Retention(AnnotationRetention.SOURCE)
    @IntDef(FLAG_PAGE_PROCESS, FLAG_PAGE_EXCEPTION, FLAG_PAGE_UNCHECKED, FLAG_PAGE_AUDIT)
    annotation class FlagPageDef
}
Другие вопросы по тегам