The invokeOnCompletion will always be invoked, but it has a number of different characteristics vs. its try counterpart.
try-catch-finally |
invokeOnCompletion |
|---|---|
|
|
GlobalScope.launch(Dispatchers.IO) {
try {
// todo| // Configure sibling composite projects (`../<project>`) by adding `composite.<project>=true` to `local.properties`. | |
| java.util.Properties() | |
| .apply { | |
| rootProject.projectDir | |
| .resolve("local.properties") | |
| .normalize() | |
| .takeIf(File::exists) | |
| ?.let { java.io.FileInputStream(it) } | |
| ?.use(::load) | |
| } |
| // swift-tools-version:5.8 | |
| import PackageDescription | |
| let package = Package( | |
| name: "MyPackage", | |
| platforms: [ | |
| .iOS(.v11) | |
| ], | |
| products: [ |
| import kotlinx.coroutines.channels.Channel | |
| import kotlinx.coroutines.coroutineScope | |
| suspend fun main() = coroutineScope<Unit> { | |
| val receive = Channel<Int>() | |
| receive.cancel() // ReceiveChannel | |
| // java.util.concurrent.CancellationException: RendezvousChannel was cancelled | |
| runCatching { receive.send(1) }.onFailure { println(it) } | |
| val send = Channel<Int>() |
| import kotlinx.coroutines.Deferred | |
| import kotlinx.coroutines.Dispatchers | |
| import kotlinx.coroutines.async | |
| import kotlinx.coroutines.delay | |
| import kotlinx.coroutines.launch | |
| import kotlinx.coroutines.supervisorScope | |
| suspend fun <T> Deferred<T>.awaitCatching(launchNumber: Int, startTime: Long) = try { | |
| await() | |
| } catch (t: Throwable) { |
The invokeOnCompletion will always be invoked, but it has a number of different characteristics vs. its try counterpart.
try-catch-finally |
invokeOnCompletion |
|---|---|
|
|
GlobalScope.launch(Dispatchers.IO) {
try {
// todo| Major type | Description | Binary | Shorthand |
|---|---|---|---|
| 0 | an unsigned integer | 000_xxxxx |
unsigned(#) |
| 1 | a negative integer | 001_xxxxx |
negative(#-1) |
| 2 | a byte string | 010_xxxxx |
bytes(n) |
| 3 | a text string | 011_xxxxx |
text(n) |
| 4 | an array of data items | 100_xxxxx |
array(n) |
| 5 | a map of pairs of data items | 101_xxxxx |
map(n) |
| pollChars | |
| ← CharData(value=a) | |
| ← CharData(value=b) | |
| pollNumbers | |
| ← NumberData(value=-1) | |
| ← NumberData(value=0) | |
| ← NumberData(value=1) | |
| pollChars | |
| ← CharData(value=c) | |
| pollNumbers |
| package com.example.myapplication | |
| import android.bluetooth.BluetoothGattCharacteristic | |
| import android.bluetooth.BluetoothGattService | |
| import com.juul.able.experimental.Gatt | |
| import com.juul.able.experimental.WriteType | |
| import com.juul.able.experimental.throwable.writeCharacteristicOrThrow | |
| import java.util.UUID | |
| class GattServiceNotFound(uuid: UUID) : Exception("GATT service $uuid not found.") |
| /** | |
| * Prevent emissions from receiver until after [trigger] emits a value that satisfies [predicate]. | |
| */ | |
| private fun <T, R> LiveData<T>.allowAfter( | |
| trigger: LiveData<R>, | |
| predicate: (R?) -> Boolean | |
| ) = object : MediatorLiveData<T?>() { | |
| private var isReady = false | |
| private var hasValue = false |