繁体   English   中英

ViewDataBinding 导致应用程序在activity.finish() 之后崩溃恢复,NPE 在视图附件期间访问 mRebindRunnable

[英]ViewDataBinding causes crash resuming app after activity.finish(), NPE on access to mRebindRunnable during view attachment

成功启动活动后崩溃表面,膨胀带有数据绑定的片段。 在根级别按下后退按钮后,应用程序(正确地)通过一个activity.finish()但将应用程序实例保留在后台。 重新启动时,应用程序在创建视图后的某个时间点崩溃(至少基于调试)。

迷恋;撞车;崩溃:

2020-08-26 20:00:50.626 9706-9706/com.org.app.dev E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.org.app.dev, PID: 9706
    java.lang.NullPointerException: Attempt to read from field 'java.lang.Runnable androidx.databinding.ViewDataBinding.mRebindRunnable' on a null object reference
        at androidx.databinding.ViewDataBinding.access$100(ViewDataBinding.java:65)
        at androidx.databinding.ViewDataBinding$6.onViewAttachedToWindow(ViewDataBinding.java:165)
        at android.view.View.dispatchAttachedToWindow(View.java:19564)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3437)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2028)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1721)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7598)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
        at android.view.Choreographer.doCallbacks(Choreographer.java:790)
        at android.view.Choreographer.doFrame(Choreographer.java:725)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

深入研究源代码,调试,我能收集到的最好的是 ViewDataBinding 看到以前绑定的视图已重新附加,并尝试与现有资源重新绑定。 但是,它显然丢失了对静态可运行对象的引用。 ViewDataBinding 的相关源代码:

    private static final OnAttachStateChangeListener ROOT_REATTACHED_LISTENER;

    static {
        if (VERSION.SDK_INT < VERSION_CODES.KITKAT) {
            ROOT_REATTACHED_LISTENER = null;
        } else {
            ROOT_REATTACHED_LISTENER = new OnAttachStateChangeListener() {
                @TargetApi(VERSION_CODES.KITKAT)
                @Override
                public void onViewAttachedToWindow(View v) {
                    // execute the pending bindings.
                    final ViewDataBinding binding = getBinding(v);
                    binding.mRebindRunnable.run();
                    v.removeOnAttachStateChangeListener(this);
                }

                @Override
                public void onViewDetachedFromWindow(View v) {
                }
            };
        }
    }

我确实注意到了来自以下内容的相同堆栈跟踪: App crash cause of data binding related to java.lang.Runnable android.databinding.ViewDataBinding.mRebindRunnable但该问题似乎与应用程序立即崩溃有关(我的仅在尝试补水后发生)。 但是从那个问题来看,我确实注意到记录我的视图标签返回空值。 我尝试在 xml 中设置一个静态标签,没有任何变化。

我尝试过的其他事情:

  • 如果我只实例化片段,则不会发生问题(但显然不会附加到框架布局
  • 没有明确的调试崩溃点(onCreateView、onViewCreated 都被调用)
  • 我尝试改变我如何膨胀,分配生命周期所有者,绑定视图模型; 没有任何变化影响崩溃。
  • 我尝试对绑定进行一些调用(invalidateAll()、unbind()),但没有成功。

同样,该问题仅在应用程序实例仍然存在但活动已被销毁时才会出现。 感谢您的任何提示!

编辑:相关代码位

活动 (Java) -

ExampleFragment exampleFragment = new ExampleFragment(exampleParameter);
FragmentManager fragmentManager = getSupportFragmentManager();

fragmentManager
        .beginTransaction()
        .add(R.id.example_frame_layout, exampleFragment, EXAMPLE_TAG)
        .commit();

片段(科特林) -

override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
): View? {
    binding = FragmentExampleBinding.inflate(inflater, container, false).apply {
        lifecycleOwner = viewLifecycleOwner
    }
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    binding.run {
        viewModel = this@ExampleFragment.viewModel
    }
}

更新

有趣的是,当我尝试将相同的片段(新实例化的)膨胀到不同的(非启动)活动时,我现在看到了这一点。 调试这个案例,除了在膨胀和返回绑定的根视图(而不是 null)之后遇到崩溃之外,我找不到任何问题。 我已经尝试使用为布局创建的静态方法以及 DataBindingUtil。 两者都经历了相同的崩溃。

尤里卡!!

<merge/>不仅不能用于<include/>布局(这里也有记录: https : //developer.android.com/topic/libraries/data-binding/expressions#includes

绑定也不适用于以<merge/>为根的<include/>布局。 这是它的样子:

<layout>
...

    <include layout="id/sub_layout"
        bind:viewModel="@{viewModel} />
...
</layout>

和问题(R.id.sub_layout.xml):

<layout>
...
    <merge>
        <TextView/>
        <ImageView/>
    </merge>
...
</layout>

奇怪的是它似乎对发射活动有效,但很高兴知道导致这种情况的症状(通货膨胀后崩溃异步)。 对于在数据绑定和错误消息方面有问题的人,我绝对建议您尝试更改您的布局。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM