Kotlin で 非同期処理 Coroutine #1 ~ launch(), async()

ネット上を調べてみてもよくわかりません。

難しい言葉や experimental な仕様の変更などあったりして。

少しづつ試してみながらマスターしていきましょう。

// build.gradle

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.22.2"

//gradle.properties

kotlin.coroutines=enable

kotlinx.coroutines/coroutines-guide-ui.md at master · Kotlin/kotlinx.coroutines

まず、これ。


for (i in 1..10) {
  Timber.d("$i")
  Thread.sleep(1000)
}

非同期にしたいですよね。
launch から始めます。


launch { // @
  for (i in 1..10) {
    Timber.d("$i")
    Thread.sleep(1000)
  }
}


launch {
  for (i in 1..10) {
    Timber.d("$i")
    delay(1000)  // @
  }
}

引数をつけて渡す。

UI :
UIスレッドで実行。

CommonPool :
バックグランドスレッドで実行。


launch(UI) {  // @
  for (i in 1..10) {
    Timber.d("$i")
    delay(1000)
  }
}


launch(CommonPool) {  // @
  for (i in 1..10) {
    Timber.d("$i")
    delay(1000)
  }
}


launch(UI + CommonPool) {  // @
  for (i in 1..10) {
    Timber.d("$i")
    delay(1000)
  }
}

launch() の戻りからキャンセルできます。


val job = launch(UI) {  // @
  for (i in 1..10) {
    Timber.d("$i")
    delay(1000)
  }
}

fab.setOnClickListener {
  job.cancel() // @
}

 

まとめ

UIスレッドに限定されたコルーチンは、UIスレッドをブロックすることなく、UI内の何かを自由に更新して中断することができます。

delay が待っている間UIスレッドはブロックされないのでUIはフリーズしません。ただ単にコルーチンを中断します。

Job.cancelは完全にスレッドセーフでノンブロッキングです。
実際に終了するのを待つことなく、コルーチンがそのジョブをキャンセルするように通知するだけです。 どこからでも呼び出すことができます。

基本的な非同期呼び出しは、launch() と async() の2つ。似ているが戻りが異なる。


USB3.0 が WiFi 2.4Ghz に干渉しすぎて無駄にケーブルやアダプタが増えて金は減る

MacにUSB3.0ケーブルを差すとはっきりWiFiの接続が切れまくる。

もしや、と思い調べてみると。

USB3.0 機器から発生する高周波ノイズも、2.4Ghz無線LAN機器に大きく干渉し、良くない影響(通信速度の低下や通信断)が発生するようです。

USB3.0機器から発生するノイズは、2.4Ghz無線LANに悪影響を与えるらしい。 - ぼくんちのTV 別館

え、中華なケーブルやアダプタって買ってみて気づくこと多くない?

ネットのレビューやランキングって当てにならなくねえ?...

Apple 公式にも。

USB 3 デバイスがコンピュータに接続されていると、Wi-Fi または Bluetooth デバイスが正常に動作しないことがあります。なぜですか?

一部の USB 3 デバイスは、無線周波数干渉を引き起こすことがあります。これによって、2.4 GHz 帯を使用する Wi-Fi および Bluetooth デバイスとコンピュータとの通信に問題が生じる場合があります。

Mac で USB デバイスを使う - Apple サポート

この、WiFiの周波数の話は以前混線が気になっていたのが、もう4年前とか。

公衆無線LANとかWiFiが途切れる場合「5GHz帯」に切り替えたほうがいいんぢゃね?

今、同じアプリで計測してみると、2.4GHzはあいかわらず混雑で、5.0GHzも混んで来ている模様。

ルータを見てみると、今では旧型となり、2.4Ghz オンリー。

当然、飛んでいるWiFiのSSIDにも -g -gw のみ。


○○-a	IEEE802.11n	5GHz帯	        600Mbps
○○-aw	IEEE802.11a	5GHz帯	        54Mbps
○○-g	IEEE802.11n	2.4GHz帯	600Mbps
○○-gw	IEEE802.11g	2.4GHz帯	54Mbps

無線LANルーターのwifiのID内にある「g」「a」「gw」「aw」の意味 | JoyPlotライフ

買い替えますか、WiFiルータ。

【価格.com】無線LANルーター(Wi-Fiルーター) | 通販・価格比較・製品情報

最近のガジェットて使えるものなのに無駄に購入したりしてません?

もう2000円のルータを買おうと思います。 ← これが原因か! (笑)

👉 「これは分からないわ…」Mac miniで2.4GHz帯のWi-Fiが全く通信できないので調べてみたら1000円くらいで買った中華製のHDDケースに付いてたUSBケーブルが原因だった - Togetter 
👉 公衆無線LANとかWiFiが途切れる場合「5GHz帯」に切り替えたほうがいいんぢゃね? 


E を出力させない Double.toPlainString()

こういうの。助かります。


double d1 = 0.00000000000000000000000000000000000000000123456789012345678901234567890d;
double d2 = 1234567890123456789012345678900000000000000000000000000000000000000000000d;
double d3 = 1234567890.1234567890123456789d;

System.out.println(BigDecimal.valueOf(d1).toPlainString());
// 0.0000000000000000000000000000000000000000012345678901234568
System.out.println(BigDecimal.valueOf(d2).toPlainString());
// 1234567890123456800000000000000000000000000000000000000000000000000000000
System.out.println(BigDecimal.valueOf(d3).toPlainString());
// 1234567890.1234567

Java の double を素直な String にしたい、E 要らない - Qiita

直感的には表示できなく、ネット上を放浪していました。

Kotlin では、Extention Functions に追加しておきますわ。


fun Double.toPlainString(): String
    = BigDecimal.valueOf(this).toPlainString()


val d1 = 0.00000000000000000000000000000000000000000123456789012345678901234567890
val d2 = 1234567890123456789012345678900000000000000000000000000000000000000000000.0
val d3 = 1234567890.1234567890123456789
val d4 = 4.34e-05
val d5 = 5.6e-07

println(d1.toPlainString())
println(d2.toPlainString())
println(d3.toPlainString())
println(d4.toPlainString())
println(d5.toPlainString())


I/System.out: 0.0000000000000000000000000000000000000000012345678901234568
I/System.out: 1234567890123456800000000000000000000000000000000000000000000000000000000
I/System.out: 1234567890.1234567
I/System.out: 0.0000434
I/System.out: 0.00000056

Java Double に toPlainString() がないのは何か理由があるのかも。とは思うが。