2017-10-29 2 views
0

私は開発者サイトからAndroidのBluetoothチャットプロジェクトに取り組んでいます。私はJavaの代わりにKotlinを使用しようとしています。私はKotlinには新しく、私のコンパニオンオブジェクトと一緒に私のinitブロックとlateinitキーワードを使用する "正しい"方法についていくつか混乱しているだけです。コードで私は投稿している私はコンパニオンオブジェクトを持っていないが、私はする必要がありますかと思っています。これまでは、主に、コンパニオンオブジェクトを使用して、javaの静的クラスメンバーをソートする方法として、またはクラス定数を含むことがありました。私のinitブロックについては、基本的にコンストラクタを使用しています。それは、クラス宣言で定義された実際のコンストラクタを渡されたメンバーの割り当てです。 lateinitに関しては、私は即座に初期化したくないメンバーを宣言するためにこれを使用していますが、nullableにしたくないことも望んでいます。これが正しい使用法なのか、そうでない場合は私が変更することを私に教えてください。ここに私のコードは次のとおりです。lateinit、initブロック、およびコンパニオンオブジェクトを使用するタイミング。 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 
    } 
} 

答えて

3

を作ることができますコンストラクタたとえば、onCreate()などのライフサイクルメソッドで変数を初期化する場合は、lateinit varを使用できます。

はまた、私はあなたがTMP変数を排除するためにあなたのinitブロックをリファクタリングと思う:

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

これで私が午前唯一の問題は、私はmmServerSocketのためのValを使用することができませんということです。プロパティを初期化または抽象化する必要があるというメッセージが表示されます。だから、lateinitを使用しないでください?ちょうどそれをnull可能なvarにする?何をお勧めしますか? –

+0

try-catchブロックでは、valを使うことはできません。try-catchを考えると、変数に有効な値が得られないことを意味します。だから私はここでのベストプラクティスは、null可能なvarを使用することだと思う。 – ItWillDo

+0

助けてくれてありがとう。私はこれらの変更を加え、すべてがうまくいっています。 –

2

これが正しい用法であるかの事の私にとって 変化にあればそうでない場合は私に知らせてください。

コードに関する2つの点が指摘されています。

  1. あなたはコンストラクタで両方の変数を初期化しているので、あなたはmmServerSocketmSocketType両方にlateinitキーワードは必要ありません。変数が作成後に初期化されていれば、必要になります。
  2. 例外をスローするケースが1つあります。変数tmpは、IOExceptionがスローされた場合はnullになります。その場合、tmpmmServerSocketを割り当てると、KotlinNullPointerExceptionが投げられます。 あなたはそれを修正するには、いくつかの可能性を持っている:あなたはcatchブロックのデフォルトのケースを扱うことができ、あなたはあなたがあなたの変数を初期化している考慮ここlateinitを必要としないmmServerSocket NULL可能、など。
関連する問題