この記事を作った動機

 Android アプリでネットワーク接続に対応する の続きの記事です。前の記事でやっていたことに関して、進展があったので、とりあえず忘れないうちに記録しようというわけです。

 まあ、理解より先に動くことを試していたので、間違ったこととかも書いていること大いにあり得ます。これはあくまで自分の理解を深めるために記事として書いてしまおうという感じです。ご注意ください。(それは他の記事でも言えることですが。。。)

コード

専用クラス(ViewModel)にて

...
class smbOperation1 : ViewModel(){
    private val userLiveData = MutableLiveData<String>()
    val user: LiveData<String> get() = userLiveData

    init {
        // trigger user load.
    }

    fun doAction() {
        viewModelScope.launch {
            val test = withContext (Dispatchers.IO) {
                testSMB()
            }
            userLiveData.value = test
        }
    }
    ...
}

アクティビティ内にて

...
class shareFolderListActivity1 : AppCompatActivity() {
// https://github.com/hierynomus/smbj

    private val smb by viewModels<smbOperation1>()

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        val debugTestStart = findViewById<Button>(R.id.debugTestStart)
        val debugText = findViewById<TextView>(R.id.resultAndDebugConsole)
        smb.user.observe (this){ message: String ->
            debugLog(message)
            debugText.setText(message)
        }
        debugTestStart.setOnClickListener{
            smb.doAction()
        }
    }
    ...
}

わかったこと(現時点での理解)

  • LiveData というのを使う方仕組みの方が新しいっぽい
  • AsyncTask クラスとは異なる、kotlin 側で用意されたスレッド管理の仕組みを使う方が簡単そう

LiveData

 UI と ViewModel クラス間におけるデータの橋渡し的なやり取りを行う。UIスレッド側で監視される変数的なものである。ViewModel クラスのインスタンスのうち、 LiveData に変更があり次第オブザーバー内に登録された処理が実行され、UIが更新される。

  • ViewModel 内のメンバ変数として
    private val userLiveData = MutableLiveData<String>()
    val user: LiveData<String> get() = userLiveData
  • Activity 内の onCrete 内にて
        val debugTestStart = findViewById<Button>(R.id.debugTestStart)
        val debugText = findViewById<TextView>(R.id.resultAndDebugConsole)
        smb.user.observe (this){ message: String ->
            debugLog(message)
            debugText.setText(message)
        }

        debugTestStart.setOnClickListener{
            smb.doAction()
        }

coroutines

 kotlin で用意された、スレッディングの仕組みだと思う。Android開発においては、例えば、コンテキストとして、以下のようなものが用意されている。

  • Dispatchers.Main
  • Dispatchers.Default
  • Dispatchers.IO

 今回は SMB のためにネットワークの処理を行うので、Dispatchers.IO のコンテキストを利用した。

suspend

 詳しいことはまだよくわかっていないが、少なくとも susupend 修飾子がついた関数は、同じように susupend 修飾子がついている関数か、viewModelScope.launchからしか呼び出して、実行することができない。

withContext

 withContext自体は、susupend 関数なので、直接通常の関数から呼び出すことはできない。以下のように、viewModelScope.launchと併用するのが、一つのwithContext関数の使い方っぽい。

        viewModelScope.launch {
            val test = withContext (Dispatchers.IO) {
                testSMB()
            }
            userLiveData.value = test
        }

 withContext関数自体は、kotlin 側で用意された、

  • Dispatchers.Main
  • Dispatchers.Default
  • Dispatchers.IO

のどれかのコンテキストを選んで、coroutines の仕組み上で何かしらの処理をさせるためにあるっぽい。

 coroutines でも書いたように、今回は、ネットワーク用のスレッドコンテキストとして、Dispatchers.IO を試した。

前の記事

次の記事

今のところなし

参考にしたサイトとか