以前のリビジョンの文書です
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) ・・・ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2" // step1 }
package com.nekotype.ips.api import android.os.AsyncTask import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import kotlinx.android.synthetic.main.activity_main.* import kotlinx.coroutines.* // step2 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // click button.setOnClickListener { println("start: ${Thread.currentThread().name}") GlobalScope.launch{ println("coroutine: ${Thread.currentThread().name}") } println("end: ${Thread.currentThread().name}") } } } ↓ start: main end: main coroutine: DefaultDispatcher-worker-1
// thread version import kotlinx.coroutines.* import java.util.concurrent.atomic.AtomicLong import kotlin.concurrent.thread fun main() { val c = AtomicLong() for (i in 1..1_000_000L) // thread だと数秒まっても終了しないので諦めた thread(start = true) { c.addAndGet(i) } println(c.get()) } ↓ // coroutines version import kotlinx.coroutines.* import java.util.concurrent.atomic.AtomicLong import kotlin.concurrent.thread fun main() { runBlocking { val sum = deferred.sumBy { it.await() } println("Sum: $sum") } } val deferred = (1..1_000_000).map { n -> GlobalScope.async { n } } // Sum: 1784293664
import kotlinx.coroutines.* import java.util.concurrent.atomic.AtomicLong import kotlin.concurrent.thread fun main() { runBlocking { val sum = deferred.sumBy { it.await() } println("Sum: $sum") } } val deferred = (1..1_000_000).map { n -> GlobalScope.async { delay(1000) n } } ↓ Sum: 1784293664
launchやasyncで新しいcoroutineを作成するが、Dispatchers.Mainで簡単にmainスレッドを呼び出せる。
今までのdoInBackgroundでpublishProgressを使ってonProgressUpdateを呼び出すようなことをしなくてよくなる。
package com.nekotype.ips.myapplication import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import kotlinx.android.synthetic.main.activity_main.* import kotlinx.coroutines.* import java.text.SimpleDateFormat import java.util.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val format = SimpleDateFormat("kk:mm:ss") Log.d("async", "${text1.text} ${format.format(Date())} : ouerLaunch1 : ${Thread.currentThread().name}\n\n") GlobalScope.launch { Log.d("async", "${text1.text} ${format.format(Date())} : inLaunch1 : ${Thread.currentThread().name}\n\n") async{ delay(3000) Log.d("async", "${text1.text} ${format.format(Date())} : async1 : ${Thread.currentThread().name}\n\n") } Log.d("async", "${text1.text} ${format.format(Date())} : inLaunch2 : ${Thread.currentThread().name}\n\n") async(Dispatchers.Main) { delay(1000) Log.d("async", "${text1.text} ${format.format(Date())} : async2 : ${Thread.currentThread().name}\n\n") } async { delay(500) Log.d("async","${text1.text} ${format.format(Date())} : async3 : ${Thread.currentThread().name}\n\n") async(Dispatchers.Main) { Log.d("async", "${text1.text} ${format.format(Date())} : inAsync3 : ${Thread.currentThread().name}\n\n") } } } Log.d("async","${text1.text} ${format.format(Date())} : ouerLaunch2 : ${Thread.currentThread().name}\n\n") } } ↓ 05:32:14 : ouerLaunch1 : main 05:32:14 : ouerLaunch2 : main 05:32:14 : inLaunch1 : DefaultDispatcher-worker-1 05:32:14 : inLaunch2 : DefaultDispatcher-worker-1 05:32:14 : async3 : DefaultDispatcher-worker-1 05:32:14 : inAsync3 : main // ⇒ worker-1 の内側からmainを呼び出している 05:32:15 : async2 : main 05:32:17 : async1 : DefaultDispatcher-worker-3
Log.d( "coroutine","start") GlobalScope.launch(Dispatchers.Main) { Log.d( "coroutine","coroutin") Text.text="click" // 画面のテキストを変更する } Log.d( "coroutine","end") ↓ 2020-01-14 06:24:17.847 7602-7602/com.nekotype.ips.coroutine D/coroutine: start 2020-01-14 06:24:17.847 7602-7602/com.nekotype.ips.coroutine D/coroutine: end 2020-01-14 06:24:17.849 7602-7602/com.nekotype.ips.coroutine D/coroutine: coroutin
private var myjob:Job? =null private var myjobs= mutableListOf<Job?>() ... myjob=GlobalScope.launch { progress_countdown.max=1000 ... // 画面を閉じた場合にコルーチンをキャンセル override fun onPause() { super.onPause() myjobs.map { Log.d("choice","cancel") it?.cancel() } }
コルーチン内で他のコルーチンの終了を待機する。
fun TestCoroutin(){ Log.d( "coroutine","start") GlobalScope.launch() { launch { Log.d( "coroutine","coroutin_inner") } Log.d( "coroutine","coroutin_outer") } Log.d( "coroutine","end") } ↓ 2020-01-14 06:29:12.311 7952-7952/com.nekotype.ips.coroutine D/coroutine: start 2020-01-14 06:29:12.340 7952-7952/com.nekotype.ips.coroutine D/coroutine: end 2020-01-14 06:29:12.347 7952-7998/com.nekotype.ips.coroutine D/coroutine: coroutin_outer 2020-01-14 06:29:12.348 7952-7999/com.nekotype.ips.coroutine D/coroutine: coroutin_inner
↓
fun TestCoroutin(){ Log.d( "coroutine","start") GlobalScope.launch() { launch { Log.d( "coroutine","coroutin_inner") }.join() // 待つ Log.d( "coroutine","coroutin_outer") } Log.d( "coroutine","end") } ↓ 2020-01-14 06:30:51.472 8058-8058/com.nekotype.ips.coroutine D/coroutine: start 2020-01-14 06:30:51.500 8058-8058/com.nekotype.ips.coroutine D/coroutine: end 2020-01-14 06:30:51.505 8058-8111/com.nekotype.ips.coroutine D/coroutine: coroutin_inner //順番が変わる 2020-01-14 06:30:51.508 8058-8110/com.nekotype.ips.coroutine D/coroutine: coroutin_outer //順番が変わる
runBlockingとasyncは戻り値をもつことができる。
asyncは非同期に処理する。asyncにはawaitでまつことができる。