web-dev-qa-db-ja.com

androidxデータバインディングライフサイクルNullPointerException

このDataBindingNullPointerExceptionの起源を見つけられないようです。 Fragmentに移動して再度上に移動するときにAndroid Navigation Architectureを使用していると、最終的に次のスタックトレースが発生します

Java.lang.NullPointerException: Attempt to invoke direct method 'void androidx.databinding.ViewDataBinding.handleFieldChange(int, Java.lang.Object, int)' on a null object reference
        at androidx.databinding.ViewDataBinding.access$800(ViewDataBinding.Java:64)
        at androidx.databinding.ViewDataBinding$LiveDataListener.onChanged(ViewDataBinding.Java:1592)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.Java:113)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.Java:126)
        at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.Java:424)
        at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.Java:376)
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.Java:355)
        at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.Java:293)
        at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.Java:333)
        at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.Java:138)
        at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.Java:124)
        at androidx.fragment.app.Fragment.performStart(Fragment.Java:2485)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.Java:1494)
        at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManager.Java:2646)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.Java:2416)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.Java:2372)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.Java:2273)
        at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManager.Java:733)
        at Android.os.Handler.handleCallback(Handler.Java:789)
        at Android.os.Handler.dispatchMessage(Handler.Java:98)
        at Android.os.Looper.loop(Looper.Java:164)
        at Android.app.ActivityThread.main(ActivityThread.Java:6938)
        at Java.lang.reflect.Method.invoke(Native Method)
        at com.Android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.Java:327)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1374)

例外に記載されているように、LiveDataライフサイクルと関係があるようです。 onPauseLiveData内のViewModelオブジェクトは、メモリのためにクリアされ、何らかの理由で再度アクセスされていると思います。

これはすべてのフラグメントで発生するので非常にランダムに見えますが、その特定のフラグメントとの間、またはアプリ内の異なるフラグメント間で継続的にナビゲートする場合のみです。フラグメントが一時停止/破棄された後は、LiveDataオブジェクトにアクセスしようとしません。これまでにこの問題を経験したことのある人を見つけることはできませんでした。問題の原因を突き止めるのは非常に困難です。

16
Neil

私は今朝同じ問題に遭遇し、私だけではないことを知って嬉しかったです。

ご存知のように確認するのは少し難しいですが、私は自分で解決したと思います。私にとって、エラーが発生するのは、viewPagerでフラグメント間をページングするときでした。フラグメントが画面外にあるときに切り離されていたと思いますが、データバインディングの更新がまだ呼び出されていました。これを確認するには、viewPagerのoffscreenPageLimitを0に設定し、エラーをずっと一貫して取得し始めました。

私の解決策は置き換えることでした:

binding.setLifecycleOwner(this);

と:

binding.setLifecycleOwner(getViewLifecycleOwner());

参照: getViewLifecycleOwner

フラグメントのビューのライフサイクルを表すLifecycleOwnerを取得します。ほとんどの場合、これはフラグメント自体のライフサイクルを反映していますが、デタッチされたフラグメントの場合、フラグメント自体のライフサイクルは、ビュー自体のライフサイクルよりもかなり長くなる可能性があります。

この変更を行って以来、エラーは発生していません。問題が解決したかどうかをお知らせください。最終的に再度エラーが発生した場合は、回答を更新しますが、これまでのところ、これで問題が解決したと確信しています。

30
Mike Simpson