非同期通信を複数行う

Androidで非同期通信を複数行うために実装したことのメモです。

Androidで通信処理を行うには、別スレッドを用いて非同期で行わないと例外が発生してしまいます。
非同期処理には何種類も方法ありますが、今回はAsyncTaskLoaderを使ってみようと思います。
実際にActivityで処理を行うときに特化します。

Activity側では、LoaderManager.LoaderCallbacksインターフェースを実装します。このインターフェースを実装する事で非同期処理後の処理などを実装できます。

流れとしては以下になります。

*①LoaderManager.initLoaderメソッドを呼び出す*

*②onCreateLoaderメソッドで非同期処理のインスタンスを作成する*

*③非同期処理が終了したら onLoadFinishedメソッドが呼び出される*

これを複数作るとなると、onCreateLoaderメソッドやonLoadFinishedメソッドが重複するのでどうしたものかと思いました。

####①並列

LoaderCallbacksインターフェースを内部クラスにして、initLoaderで渡すようにすると、複数の非同期処理を行うことができます。

```kotlin:MainActivity.kt
class MainActivity: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // 省略

        confirmButton.setOnClickListener {
            supportLoaderManager.initLoader(0,null, Callback1(this))
            supportLoaderManager.initLoader(1,null, Callback2(this))

        }
    }

  private class Callback1(context: Context) : 
  LoaderManager.LoaderCallbacks<Rss> {

      override fun onLoaderReset(loader: Loader<Rss>?) {
          // 処理
      }

      override fun onLoadFinished(loader: Loader<Rss>?, data: Rss?) {
          // 処理
      }

      override fun onCreateLoader(id: Int, args: Bundle?){
          // 処理
      }
  }

  private class Callback2(context: Context) : LoaderManager.LoaderCallbacks<Feed> {

      override fun onLoaderReset(loader: Loader<Feed>?) {
          // 処理
      }

      override fun onLoadFinished(loader: Loader<Feed>?, data: Feed?) {
          // 処理
      }

      override fun onCreateLoader(id: Int, args: Bundle?){
          // 処理
      }
   }
}
```

ただ、上記のようにすると1個目が終わってから2個目とはならないので、1個目が終わってから2個目のように直列にするためには実装を少し変えないといけません。

####②直列

この場合は、1個目のonLoadFinishedで2個目のinitLoaderを呼び出すことで実現できます。

```kotlin:MainActivity.kt
class MainActivity: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // 省略

        confirmButton.setOnClickListener {
            supportLoaderManager.initLoader(0,null, Callback1)

        }
    }

　　// LoaderCallbacksの関数をオーバーライドして、処理を変更した「オブジェクト」を作成する
    private val Callback1 : LoaderManager.LoaderCallbacks<Feed> = object : LoaderManager.LoaderCallbacks<Feed> {

        override fun onLoaderReset(loader: Loader<Feed>?) {
            // 処理
        }

        override fun onLoadFinished(loader: Loader<Feed>?, data: Feed?) {
            supportLoaderManager.initLoader(1, args
, Callback2)
        }

        override fun onCreateLoader(id: Int, args: Bundle?){
        　　// 処理
    　　}

    }
    private val Callback2 : LoaderManager.LoaderCallbacks<Feed> = object : LoaderManager.LoaderCallbacks<Feed> {
        override fun onLoaderReset(loader: Loader<Feed>?) {
            // 処理
        }

        override fun onLoadFinished(loader: Loader<Feed>?, data: Feed?) {
            // 処理
        }

        override fun onCreateLoader(id: Int, args: Bundle?){
            // 処理
        }
    }
}
```

実際使ってみて今回記載したこと以外にも、実行中かとかの考慮をしないといけないので、結構大変なイメージを持ちました。
RxJavaとかを使ったほうがまだ見やすい実装ができそうだと感じました。


#####参照

[Androidの非同期処理でAsyncTaskLoaderを使う](https://araramistudio.jimdo.com/2018/01/17/android%E3%81%AE%E9%9D%9E%E5%90%8C%E6%9C%9F%E5%87%A6%E7%90%86%E3%81%A7asynctaskloader%E3%82%92%E4%BD%BF%E3%81%86/)
[Kotlinの内部クラスを理解する](https://qiita.com/kaleidot725/items/f2c6611648b04f7f41db)