2017-10-29 7 views
0

Ich arbeite an der Android-Bluetooth-Chat-Projekt von der Entwickler-Website und ich versuche, Kotlin anstelle von Java zu verwenden. Ich bin neu in Kotlin und ich habe nur einige Verwirrung über die "richtige" Möglichkeit, meine init Block und Lateinit Keyword zusammen mit meinen Begleiter Objekte zu verwenden. In dem Code, den ich poste, habe ich kein Begleitobjekt, aber ich frage mich, ob ich sollte. Bisher verwende ich hauptsächlich nur ein Begleitobjekt, um die statischen Klassenmitglieder von Java nachzuahmen oder um Klassenkonstanten zu enthalten. wie für meinen init Block verwende ich im Grunde für einen Konstruktor. Das ist anders, dass die Zuweisung von Membern über den tatsächlichen Konstruktor, der in der Klassendeklaration definiert wurde, übergeben wurde. Was später angeht, benutze ich das, um Mitglieder zu deklarieren, die ich nicht sofort initialisieren möchte, aber auch keine NULL-Werte machen möchte. Bitte lassen Sie mich wissen, ob dies die richtige Verwendung ist oder ob ich etwas ändern muss, wenn dies nicht der Fall ist. Hier ist mein Code:Wann Lateinit, Init-Block und Companion-Objekt zu verwenden. Kotlin

inner class AcceptThread(val secure:Boolean) : Thread(){ 
    lateinit var mmServerSocket:BluetoothServerSocket 
    lateinit var mSocketType:String 

    init { 
     var tmp:BluetoothServerSocket? = null 
     mSocketType = if (secure) "Secure" else "Insecure" 

     try { 
      if (secure){ 
       tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_SECURE) 
      } else{ 
       tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, UUID_INSECURE) 
      } 
     }catch (ioe:IOException){ 
      Log.e(TAG, "Socket Type: $mSocketType listen() failed", ioe) 
     } 
     mmServerSocket = tmp!! 
     mState = STATE_LISTEN 
    } 
} 

Antwort

3

Sie brauchen nicht lateinit hier Erwägen Sie Ihre Variablen sind in der Initialisierung der Konstruktor. Wenn Sie beispielsweise die Variablen in einer Lebenszyklusmethode wie onCreate() initialisieren würden, könnten Sie eine lateinit var verwenden.

Außerdem glaube ich, Sie init Block Refactoring könnte die Variable tmp zu beseitigen:

inner class AcceptThread(val secure:Boolean) : Thread() { 
val mmServerSocket: BluetoothServerSocket 
val mSocketType: String = if (secure) "Secure" else "Insecure" 

init { 
    try { 
     mmServerSocket = if (secure) { 
      mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_SECURE) 
     } else { 
      mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, UUID_INSECURE) 
     } 
    } catch (ioe: IOException) { 
     Log.e(TAG, "Socket Type: $mSocketType listen() failed", ioe) 
    } 
    mState = STATE_LISTEN 
} 
+0

das einzige Problem, das ich mit diesem habe ist, dass ich nicht in der Lage bin Val zu verwenden für mmServerSocket. Ich bekomme eine Nachricht, dass die Eigenschaft initialisiert oder abstrakt sein muss. Also nicht LateInit benutzen? Machen Sie es einfach als Nullable Var? Was würdest du vorschlagen? –

+0

Also scheinbar mit try-catch-Blöcken kann man val nicht verwenden, was angesichts des try-catch Sinn macht, impliziert, dass man nicht garantiert, einen gültigen Wert für die Variable zu erhalten. Also ich denke, die beste Vorgehensweise wäre hier, eine Nullable var zu verwenden. – ItWillDo

+0

ok danke für die Hilfe. Ich habe diese Änderungen vorgenommen und alles funktioniert gut. –

2

Bitte lassen Sie mich wissen, ob dies die korrekte Verwendung oder eine Sache ist für mich zu ändern, wenn dies nicht der Fall.

Es gibt zwei Dinge, die ich auf Ihren Code hinweisen werde.

  1. Sie brauchen nicht die lateinit Schlüsselwort sowohl mmServerSocket und mSocketType, weil Sie beide Variablen im Konstruktor initialisiert wird. Sie hätten es benötigt, wenn die Variablen nach der Erstellung initialisiert worden wären.
  2. Es gibt einen Fall, der eine Ausnahme auslösen kann. Die Variable tmp kann null sein, wenn eine IOException ausgelöst wird. In diesem Fall wird beim Zuweisen von tmp zu mmServerSocket ein KotlinNullPointerException ausgelöst. Sie haben mehrere Möglichkeiten, es zu beheben: Sie können einen Standardfall im Block catch verarbeiten kann, können Sie mmServerSocket nullable machen, etc ..
Verwandte Themen