DataBindingUtil将布局充气为null。

5

我正在使用Android Jetpack导航组件开发单个活动应用程序。在其中一个片段中,我使用了内置的数据绑定工具。奇怪的是,虽然它在上周还能正常工作,但今天却突然完全崩溃,原因似乎无法解释。

设置:
我使用以下布局文件来使用绑定的片段:

<?xml version="1.0" encoding="utf-8"?>
<layout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
    </data>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/example_layout_root"
        tools:context=".example.ExampleFragment"
        android:background="@color/main_1"
        >

        ...

    </ScrollView>
</layout>

我已经剥离了主要内容,但是它显示我的根元素是一个<layout>元素,其中包含数据和片段布局部分的定义。
片段代码如下:
class ExamleFragment : Fragment() {

    private val viewModel: ExampleViewModel by sharedViewModel()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        val binding : FragmentExampleBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_example, container, false)
        // This one also does not work
        // val binding = FragmentExampleBinding.inflate(inflater, container, false)
        binding.vm = viewModel
        binding.lifecycleOwner = this

        return binding.root
    }
}

我使用Koin将viewmodel注入fragment中。
当我尝试使用DataBindingUtil或生成的FragmentExampleBinding类膨胀布局时,会导致以下异常:

java.lang.IllegalStateException: FragmentExampleBin…flater, container, false) must not be null at com.example.fragments.ExampleFragment.onCreateView(ExampleFragment.kt:38) at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698) at ...

堆栈直接进入操作系统领域,因此基本上没有提供任何有用信息。我无法弄清楚为什么结果是null。

我尝试过的解决方法:

  • 我尝试使用inflater.inflate(...)来填充布局,它可以正常工作,但这样我就不能使用数据绑定。

  • 我尝试从布局描述中删除所有不必要的内容,但仍然无法正常工作。

  • 我尝试还原到以前的提交版本(最早的具有绑定功能的工作版本),即使以前可以正常工作,现在也不能正常工作。

  • 我甚至重新启动和重置模拟器,尝试不同的镜像,但都无济于事。

有人遇到过类似的情况吗?代码在周末确实“崩溃”了,因为我在上周五测试它时它可以正常工作。

编辑:
好吧,我不知何故修复了它。
我开始尝试创建另一个使用数据绑定的fragment,以查看所有片段是否都存在问题,新的片段似乎可以正常工作,但奇怪的是,旧的不起作用即使它们基本相同。
因此,我进行了清理+重新构建(我发誓我会将其作为第一次修复问题),这种方法竟然有效了。


1
天哪,我清理和重建了多少次,无效化缓存,都没用。我只是把 XML 和类名改成其他的,然后一切就正常工作了。这是什么鬼啊。 - Vik
@Vik的解决方案对我有用……我没有多模块项目,重命名xml +类有效。 - Z-100
4个回答

7
在我的多模块项目中,这个问题的原因是存在一些包名称冲突。
如果你遇到这种错误没有明显的原因,请仔细检查启用数据绑定的模块的AndroidManifest.xml文件。
确保所有启用数据绑定的模块使用唯一的包名称解决了我的问题。
我花了几个小时才找到这个问题的根源,希望其他人能阅读这个答案并不要浪费那么多时间。

2
现在,还要看一下 build.gradle 中的 android { namespace },它也会导致同样的问题。 - Dmitrii Leonov

0
在我的情况下,我只是忘记给我的片段类添加@AndroidEntryPoint

0

这样做:

class ExamleFragment : Fragment() {

        private val viewModel: ExampleViewModel by sharedViewModel()
        lateinit binding:FragmentExmaple

        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            // Inflate the layout for this fragment
             binding = DataBindingUtil.inflate(inflater, R.layout.fragment_example, container, false)

            binding.vm = viewModel
            binding.lifecycleOwner = this

            return binding.root
        }
    }

请把您的错误信息粘贴在这里


我认为这可能是Koin的问题,你能否通过发送你的错误日志来帮助我解决呢? - freedom chuks
我得到的错误是:java.lang.IllegalStateException: DataBindingUtil.inflate(…, container, false) must not be null。这是因为我将结果为空对象分配给了一个非空字段。根本原因是一样的:膨胀导致了一个空对象,我无法弄清楚为什么会这样。 - pappbence96
我已经编辑了帖子,并加入异常堆栈跟踪信息。删掉其中仅包含操作系统代码的那部分,因为它跟我的问题并没有实质性的关联。 - pappbence96
1
当根布局不是充气绑定布局时,就会出现这种情况。你应该删除你的lateinit绑定:FragmentExmaple,删除与绑定相关的任何导入,进入你的布局中删除布局标签,右键转换为数据绑定并重新构建,然后添加回你的lateinit绑定:FragmentExmaple,它应该可以解决问题。 - freedom chuks
我不是很明白发生了什么,但在回滚到之前的工作提交后,然后多次运行Clean + Rebuild,它就...自己修复了?我猜可能是一些生成的代码出了问题,但我不确定。 - pappbence96

0
不要在片段中使用DataBindingUtil,运行应用程序一次后,Android Studio将生成一个基于xml文件名称的绑定类,对于您的情况,xml文件名为fragment_example,因此生成的类将是FragmentExampleBinding,然后您可以像这样调用FragmentExampleBinding.inflate(....):
val binding = FragmentExampleBinding.inflate(inflater, container, false);

1
我已经尝试过这样膨胀,但遗憾的是它仍然导致一个“null”对象被膨胀。我不明白的是,几天前使用完全相同的代码时它还可以正常工作。 - pappbence96
可能是您的布局文件出了问题,在膨胀期间抛出了异常,有任何日志吗? - MichaelStoddart
在我的情况下,直接使用生成的类名进行膨胀是有效的。但是DataBindingUtil.inflate返回了空值。而且这是一个活动。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接