通知が来ない「通知の自動調整」はOFFに。

「AIが判別」ということにして挙動の基準がユーザーにわからない機能って問題になることが多いです。

👉 LINEやGmailの通知が来ない慢性トラブルの原因がようやく判明?「通知の自動調整」の模様 | スマホダイジェスト 

しかも、機能をOFFにする設定が深く遠い。


設定

 ↓

アプリと通知

 ↓

特別なアプリアクセス

 ↓

通知の自動調整

 ↓

なし

notification-off

おせっかいな機能うざいですね。

Androidの通知機能は、これまでも混乱を招くことが多く、最も分かりづらい機能といってもいいでしょう。

👉 消した通知「通知履歴」をすばやく見る方法【Android11】 
👉 通知が来ない、遅れるときに見直すべき「電池(バッテリー)の最適化」 
👉 【Android Pie】「通知」設定のシンプルな考え方 


【Kotlin】StateFlow は distinctUtilChanged 不要

distinctUntilChanged

StateFlow のインスタンスは、distinctUtilChanged 演算子がに適用されているように動作するので、distinctUntilChanged を StateFlow に適用しても効果はないことに注意してください。

👉 distinctUntilChanged 

オペレータの組み合わせ
flowOn、conflate、buffer CONFLATED/RENDEZVOUS、capacity、distinctUntilChanged、cancelable のいずれかの演算子を StateFlow に適用しても効果はありません。

👉 StateFlow 

SharedFlow で StateFlow を作ることができます。StateFlow は ある設定をした SharedFlow です。



👉 StateFlow の View への公開 
👉 【MVVM】Flow vs LiveData 
👉 【Kotlin】SharedFlow と BroadcastChannel 


StateFlow の View への公開

以下のような ViewModel があったとして、バッキングプロパティ部分。

どう書いてますか。


class CounterModel {
  private val _counter = MutableStateFlow(0)

  ??? counter ??? = _counter ???

  fun inc() {
    _counter.update { count -> count + 1 } 
  }
}

以下の登場時の開発の様子を参考に。

Introduce StateFlow
👉 Introduce StateFlow · Issue #1973 · Kotlin/kotlinx.coroutines 

StateFlow は、状態を表す更新可能な値の Flow です。

- StateFlow インターフェイスは、現在の値にアクセスするための読み取り専用で、値の更新を collect するための Flow を実装しています。

- MutabaleStateFlow インターフェースは、値を変更する操作を追加しています。

- MutableStateFlow(x) のコンストラクタ関数が用意されています。この関数は、与えられた初期値を持つ MutableStateFlow の実装を返します。値への高速で非リアクティブなアクセスが必要な場合は StateFlow として、値への更新のリアクティブな表示のみが必要な場合は Flow として、外部に公開することができます。

次のようにまとめることができます。


package kotlinx.coroutines.flow

interface StateFlow<T> : Flow<T> {
  val value: T // always availabe, reading it never fails
}

interface MutableStateFlow<T> : StateFlow<T> {
  override var value: T // can read & write value
}

fun <T> MutableStateFlow(value: T): MutableStateFlow<T> // constructor fun

よって、以下、ありがちな記述。(ないか。)


var counter = _counter // NG


val counter = _counter // NG


val counter: MutableStateFlow<Int> = _counter // NG


val counter: StateFlow<Int> = _counter // NG


val counter get() = _counter // NG


val counter: MutableStateFlow<Int> get() = _counter // NG

開発者の間でも、好き嫌いはあるようですが、以下の2パターンが良さげ。Read Only であることが大事。


val counter: StateFlow<Int> get() = _counter  // OK


val counter = _counter.asStateFlow()  // OK

よって、


class CounterModel {
  private val _counter = MutableStateFlow(0)

  val counter = _counter.asStateFlow()

  fun inc() {
    _counter.update { count -> count + 1 } 
  }
}

最近の言語の仕様は、オフィシャルドキュメントでは分かりずらいポリシーが多くあるように思います。

👉 【MVVM】 ViewModel の_プロパティ記述 hatena-bookmark

👉 【MVVM】 Kotlin Flow で使える5つの利用パターン 
👉 StateFlow は distinctUtilChanged 不要