2017-09-17 2 views
2

Ich habe eine abstrakte Klasse mit für listen api Rückruf wie unten. ApiRs ist ein übergeordnetes Objekt, das jedes API-Antwort-Objekt von ihm erbtWildcards generische in Kotlin für Parameter

abstract class ApiCallback<in T : ApiRs> { 

    open fun onSucceed(apiRsModel: T) {} 

    open fun onFailed(code: Int, 
         message: String) { 
    } 
} 

und ich schreibe auch eine Funktion des Netzwerkstatus vor Anforderung api zu überprüfen, ob Netzwerk nicht angeschlossen ist, dann wird es auslösen onFailed

fun isNetworkAvailable(apiCallback: ApiCallback<ApiRs>?, 
          context: Context): Boolean{ 
     val connectivityManager = context 
       .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 
     val networkInfo = connectivityManager.activeNetworkInfo 

     // device network unreachable 
     if (networkInfo == null 
       || !networkInfo.isConnected) { 
      // callback with network error 
      apiCallback?.onFailed(code, message) 
      return false 
     } 

     return true 
    } 

der Parametertyp ApiCallback<ApiRs>? eigentlich möchte ich es wie ApiCallback<? extends ApiRs>? schreiben, aber Kotlin hat keine Wildcard. Wenn ich die generisch ApiCallback<out ApiRs>? ersetzen, wird es einen Fehler zeigt

Projektion wird mit der Varianz der entsprechenden Typ Parameter von ApiCallback

Konflikt Gibt es eine Möglichkeit, es zu beheben? oder habe ich einfach falsches Konzept von Kotlin generic?


2017/09/18 Update - Der richtige Weg ist:

Methode:

fun <T : ApiRs> isNetworkAvailable(apiCallback: ApiCallback<T>?, 
             context: Context): Boolean { 
     val connectivityManager = context 
       .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 
     val networkInfo = connectivityManager.activeNetworkInfo 

     // device network unreachable 
     if (networkInfo == null 
       || !networkInfo.isConnected) { 
      // callback with network error 
      callbackWithFailed(
        apiCallback, 
        ApiError.API_ERROR_CODE_0, 
        context.getString(R.string.api_error_code_0)) 
      return false 
     } 

     return true 
    } 
+0

'ApiCallback ' dies wird jede Art von 'ApiRs' nehmen. Siehe Sternprojektionen https://kotlinlang.org/docs/reference/generics.html#star-projections –

+0

Funktioniert nicht, wenn ich 'ApiCallback ' verwende, dann wird die obige Warnung – Ivan

+0

@NikolaDespotoski anzeigen. Jede API, die ApiRs erweitert, wird akzeptiert, aber ohne eine weitere Umwandlung haben Sie nur die Funktionen, die Ihre ApiRs-Klasse bietet. – creativecreatorormaybenot

Antwort

1

Ich verstehe, dass Sie apiCallback: ApiCallback<ApiRs>? in Ihrer Methode in einer Art und Weise akzeptieren möchten, dass die generische Typ von ApiCallback kann ApiRs selbst oder einer seiner Subtypen sein. Anstelle von Wildcards hat Kotlin upper bounds. Sie können die Funktion wie folgt erklären:

fun <T: ApiRs> isNetworkAvailable(apiCallback: ApiCallback<T>?, 
         context: Context) 
+0

Thanks! Deine Lösung macht sehr viel Sinn! – Ivan