2016-03-13 14 views
20

Sviluppo applicazioni Android e utilizzo spesso annotazioni come controlli dei parametri del tempo di compilazione, principalmente Android support annotations.Come utilizzare le annotazioni typedef di Android Support in kotlin?

Esempio di codice 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; 
    } 
} 

non voglio usare le enumerazioni a causa della loro problemi di prestazioni in Android. Il convertitore automatico di Kotlin genera solo codice non valido. Come faccio a utilizzare l'annotazione @IntDef in kotlin?

+1

È possibile utilizzare le enumerazioni liberamente, non sono 'lenti' in alcun senso (http://stackoverflow.com/questions/5143256/why-was-avoid-enums-where -solo-solo-bisogno-ints-removed-from-androids-performanc) –

+0

@AlexanderUdalov, 1) https://www.youtube.com/watch?v=Hzs6OBcvNQE 2) le enumerazioni non sono parcellizzabili per impostazione predefinita che aggiunge anche boilerplate codice quando è necessario passare ai parametri di intento 3) quando il valore ricevuto dalla rete il modo di convertirlo in enum è oscuro ed elimina la sicurezza dell'enum. – curioushikhov

+1

@curioushikhov ProGuard "semplifica i tipi di enum in costanti intere, quando possibile" ([Ottimizzazioni] (http://proguard.sourceforge.net/manual/optimizations.html)). – mfulton26

risposta

24

In realtà è possibile utilizzare l'annotazione @IntDef supporto definendo i valori al di fuori della classe di annotazione come const val s.

Usando il tuo esempio:

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 
    } 
} 

Si noti che a questo punto il compilatore sembra richiedere il tipo Long per la @IntDef annotazioni invece di effettive Int s.

+9

Ho fatto questo, ma Kotlin non sembra affatto imporre questo vincolo. Posso fornire qualsiasi int/long in cui '@ Speed' è richiesto, e non gli interessa. – AutonomousApps

+1

Btw, richiede un 'Long' perché' @ IntDef' è definito come un array di 'long' -' long [] value() default {}; ' – AutonomousApps

8

Attualmente non c'è alcun modo per ottenere esattamente questo in Kotlin, poiché una classe di annotazione non può avere un corpo e quindi non è possibile dichiarare una costante al suo interno che sarebbe elaborata da IntDef. Ho creato un problema nel tracker: https://youtrack.jetbrains.com/issue/KT-11392

Per il tuo problema però, ti consiglio di usare un enum semplice.

2

Utilizzare questa:

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 
} 
Problemi correlati