クラス図
クラス関係
矢印でクラス同士を結ぶ事ができる。 この際、その関係の種類によって矢印の形が異なる。
関係 | 意味 | 備考 | 図 |
---|---|---|---|
Extension | 継承 | ||
Aggregation (集約) | has-a | 授業(親)と生徒(子)といった関係を表す。また授業を消したからと言って、生徒は消えない。 | |
Composition | part-of | 家(親)と部屋(子)といった関係を表す。部屋は家と切り離して存在しない |
Note: Aggregation vs Composition
- 親を消したら子も消えるのかどうか
- 消える → Composition
- 消えない → Aggregation
参照
https://www.visual-paradigm.com/guide/uml-unified-modeling-language/uml-aggregation-vs-composition/
ザリガニの鳴くところ
ネタバレあり
続きを読むカスタムコルーチンスコープの作成
CoroutineScopeは実装することが出来る。
interface CoroutineScope
CoroutineScope概要
launch
やasync
といった全てのコルーチンビルダーはCoroutineScope
を拡張し、全ての要素とキャンセルを自動的に伝播するために、そのcoroutineContext
を継承する。
単独のスコープインスタンスを取得する方法は、CoroutineScope()
もしくはMainScope()
ファクトリ関数である。
これらが必要なくなった際は、スコープのキャンセルに対して注意を取り計らう。
追加的なcontext要素は、[plus](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/plus.html)
演算子を使うことで追加することが出来る。
カスタムコルーチンの作成
import kotlinx.coroutines.* import kotlin.coroutines.* class CustomScope : CoroutineScope { // ルートjob val job = Job() override val coroutineContext: CoroutineContext get() = job // + Dispatchers.IO Dispacherを指定しなかった場合は、Dispachers.Defaultが使用される fun <T> delayRun(f: ()->T): Job { // launchメソッドが自動導出される return launch { delay(1000) f() } } }
launch
メソッドなどが自動導出される
Android KTXを
Android KTXとは
Android JetpackのKotlin拡張をまとめたライブラリ。
以下のKotlinの機能を用いた拡張が用意されている
- Extension functions
- Extension properties
- Lambdas
- Named parameters
- Parameter default values
- Coroutines
サンプル SharedPreference
KTXを用いなかった場合
sharedPreferences .edit() .putBoolean("key", value) .apply()
KTXを用いた場合
sharedPreferences.edit { putBoolean("key", value) }
編集と同時にコミットも出来る
// Commit a new value sychronously sharedpreferences.edit(commit = true) { putBoolean("key", value) }
ViewModelの生成と初期化方法
ViewModel
import androidx.lifecycle.ViewModel class UserViewModel(name: String, age: Int, gender: Int) : ViewModel() { val name = name val age = age val gender = gender }
ViewModelProviderを使う
val viewModel = ViewModelProvider(this, object : ViewModelProvider.NewInstanceFactory() { override fun <T : ViewModel?> create(modelClass: Class<T>): T { return UserViewModel("Tanaka", 27, 1) as T } }).get(UserViewModel::class.java) Log.d("MainActivity", "${viewModel.name}, ${viewModel.age}, ${viewModel.gender}")
Android KTXを使う
Android KTXでは、Delegated propertiesを使って、ViewModelの生成と初期化、またActivityのViewModelの共有を行うことが出来る。
dependencyの追加
dependencies { implementation "androidx.core:core-ktx:1.6.0" }
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha02" }
viewModels
val viewModel: UserViewModel by viewModels<UserViewModel>() { object : ViewModelProvider.NewInstanceFactory() { override fun <T : ViewModel?> create(modelClass: Class<T>): T { return UserViewModel("Tanaka", 27, 1) as T } } }
参照
ViewModelProvider
https://developer.android.com/reference/android/arch/lifecycle/ViewModelProvider#viewmodelprovider_2
Android KTX
https://developer.android.com/kotlin/ktx
How to instantiate ViewModel in AndroidX
https://stackoverflow.com/questions/54313453/how-to-instantiate-viewmodel-in-androidx
コルーチン Coroutin
コルーチン
使うにあたって
dependencyの追加
https://github.com/Kotlin/kotlinx.coroutines#using-in-your-projects
Gradleの場合
dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0' }
import
App.kt
import kotlinx.coroutines.*
About コルーチン in Kotlin
非同期関数
async
に相当する関数を生成する。
// launch内部は非同期で実行される launch { println("Hello World") }
生成と実行
コルーチンスコープ内部で生成することが出来る
// コルーチンスコープの生成 runBlocking { // this: CoroutineScope // コルーチンの生成 (launchは、CoroutineScopeのメソッド) launch { } }
Job
CoroutineScope.launch()
によって生成されるコルーチンはJob
としてその参照を返す。
fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job
カレントスレッドをブロックしないで、新しいコルーチンを起動し、Job
としてコルーチンの参照を渡す。
このjobがキャンセルされたとき、コルーチンがキャンセルされる。
サスペンド関数
コルーチンの実行を中断する関数。 await
に相当する関数。
suspend
修飾子を関数につける。
App.kt
import kotlinx.coroutines.* // サスペンド関数 (コルーチンを中断する) suspend fun doWorld() { delay(1000L) println("World") } fun main() { runBlocking { doWorld() // 完了まで中断する println("Hello") } } /* 出力 World Hello */
コルーチンコンテキスト
インデックスされたElementの集合インスタンスを表す。 コンテキスト同士を結合して新たなコルーチンコンテキストを作ることも出来る
open operator fun plus( context: CoroutineContext ): CoroutineContext (source)
class MyActivity : Activity(), CoroutineScope { private val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job
Job
Elementの一種。 コルーチンへの参照を表すコルーチンコンテキスト。
CoroutineDispatcher
Elementの一種。 コルーチンを実行するスレッドを表すコルーチンコンテキスト。
CoroutineDispatcherとして用意されている。
- Dispatchers.Default - タスクは、適切なバックグラウンドスレッドに読み込まれるように設計されたCorountineDispatcher。
- Dispatchers.IO - IOタスクをブロックするスレッドの共有プールに、予め読み込んでおくために設計されたCorountineDispatcher。
- Dispatchers.Main - メインスレッド上で動作することが保証されたCorountineDispatcher。
- Dispatchers.Unconfined
コルーチンスコープ
- コルーチンコンテキストを持つ
- コルーチンを起動するメソッドを持つ
- launc
- async
- promise
- ...
生成方法
両者の違いは、CorountineDispatcherが異なる。
CoroutineScope()
- Dispatchers.DefaultMainScope()
- Dispatcher.Main
まとめ
- コルーチンコンテキストはElementの集合を表す
- Jobは、コルーチンへの参照を表すElementであり、コルーチンコンテキスト
- CorutinDispatherは、タスクを実行するスレッドを表すElementであり、コルーチンコンテキスト
- コルーチンスコープはコルーチンコンテキストを持つ