web-dev-qa-db-ja.com

onClearedは、フラグメントに添付されたViewModelで呼び出されていません

アプリがバックグラウンドに移行したときにViewModel.OnCleared()が呼び出されていないときに問題が発生しました(_Don't keep activities_が有効になっている場合でも)が、Fragment.onDestroy()が実際に呼び出されていることがわかります。

次のコードの何が問題になっている可能性がありますか?このシナリオで実際に呼び出されるようにViewModel.OnCleared()を作成するにはどうすればよいですか?

ViewModel:

_class ViewModelFirst(application: Application) : AndroidViewModel(application) {

    companion object {
        private const val TAG = "ViewModelFirst"
    }

    init {
        Log.v(TAG, "Created")
    }

    override fun onCleared() {
        super.onCleared()
        Log.v(TAG, "onCleared")
    }
}
_

断片:

_class FragmentFirst : Fragment() {

    companion object {
        private const val TAG = "FragmentFirst"
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        ViewModelProviders.of(this).get(ViewModelFirst::class.Java)

        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.v(TAG, "onDestroy")
    }
}
_

アクティビティ:

_class MainActivity : AppCompatActivity() {

    companion object {
        private const val TAG = "MainActivity"
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction().replace(R.id.container, FragmentFirst()).commit()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.v(TAG, "onDestroy")
    }    
}
_

自分自身に答えてください:

これはcom.Android.support:appcompat-v7:27.1.0のバグです

次の依存関係を使用すると、この問題が発生します。

_implementation 'com.Android.support:appcompat-v7:27.1.0'
implementation "Android.Arch.lifecycle:extensions:1.1.0"
_

_appcompat-v7_ 27.1.0-> 27.0.2のバージョンを変更すると、ViewModel.OnCleared()は期待どおりに機能します(アプリがバックグラウンドに移行したときに呼び出しがあります)。

_appcompat-v7:28.0.0-alpha1_も同様に機能しますが、これは_appcompat-v7:27.1.0_のみの問題のようです。

更新(2018年6月)

@Akshayが言ったように、バグは27.1.1でちょっと修正されました。しかし、残念ながら完全ではありません。

次のシナリオはまだ修正されていません。

  1. _Don't keep activities_を有効にします。
  2. アプリを起動します。
  3. ホームボタンを押します。

27.0.2では、logcatに次の出力があります。

_V/ViewModelFirst: Created
V/ViewModelFirst: onCleared
V/FragmentFirst: onDestroy
V/MainActivity: onDestroy
_

これは完全に正しいです。

しかし、27.1.1から28.0.0-alpha3まで、logcatに次の出力があります。

_V/ViewModelFirst: Created
V/FragmentFirst: onDestroy
V/MainActivity: onDestroy
_

アクティビティとフラグメントが破棄されたことがわかりますが、viewModelはonClearedで通知されませんでした。

_Don't keep activities_が無効になり、バックグラウンドのアプリがAndroid(別のアプリが大量のリソースを要求しているため)によって自然にアンロードされる場合に備えて、 viewModel.onCleared()が呼び出されないときは、非常に悲しいことです。

P.S.ここにコードをプッシュしました: https://github.com/allco/onClearedInvestigation

そしてここでGoogleに問題を報告しました: https://issuetracker.google.com/issues/110285295

更新(2018年8月)

28.0.0-rc01でこの問題は解決されました。わーい!

10

これはサポートライブラリv27.1.0の問題であり、サポートライブラリv27.1.1で修正されています。

以前に報告されたバグがあります https://issuetracker.google.com/issues/7413925

詳細については、次のリンクを参照してください: https://developer.Android.com/topic/libraries/support-library/revisions

7
Akshay Chordiya