java.lang.IllegalStateException: DataBindingUtil.inflate<ViewDataBinding>(...) 在尝试使用 DataBindingUtil 膨胀时不能为 null
java.lang.IllegalStateException: DataBindingUtil.inflate<ViewDataBinding>(...) must not be null while trying to inflate using DataBindingUtil
我有一个 BaseFragment class:
abstract class BaseFragment: Fragment(), View.OnClickListener {
private lateinit var mBinding: ViewDataBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mBinding = DataBindingUtil.inflate<ViewDataBinding>(inflater, getLayoutId() , container, false)
return mBinding.root
}
abstract fun getLayoutId(): Int
abstract fun afterOnViewCreated()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
afterOnViewCreated()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
}
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
}
override fun onClick(v: View?) { }
fun getViewDataBinding(): ViewDataBinding {
return mBinding
}
fun setClickListener(vararg views: View) {
views.forEach { view -> view.setOnClickListener(this) }
}
}
我将其扩展以创建这样的新片段:
class HomeFragment : BaseFragment() {
private lateinit var homeViewModel: HomeViewModel
override fun getLayoutId(): Int {
return R.layout.fragment_home
}
override fun afterOnViewCreated() {
activity?.let{
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
}
//TODO:
}
}
但是,我遇到了这个崩溃:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mu.chatonymous, PID: 23328
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MainActivity}: java.lang.IllegalStateException: DataBindingUtil.inflate<…nt_home, container, false) must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3318)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3429)
at android.app.ActivityThread.-wrap12(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2009)
at android.os.Handler.dispatchMessage(Handler.java:109)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7555)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)
Caused by: java.lang.IllegalStateException: DataBindingUtil.inflate<…nt_home, container, false) must not be null
at com.mu.chatonymous.ui.base.BaseFragment.onCreateView(BaseFragment.kt:21)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2612)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:874)
at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2087)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1861)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1817)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1717)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2650)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2600)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2639)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:897)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1228)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1293)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2646)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2600)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:176)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1340)
at android.app.Activity.performStart(Activity.java:7364)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3281)
这是我的应用级别 build.gradle 文件:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'io.fabric'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.mu.chatonymous"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}
//androidx
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.lifecycle:lifecycle-runtime:2.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
kapt 'androidx.lifecycle:lifecycle-compiler:2.1.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
//for selection single or multiple items in recycler view
implementation 'androidx.recyclerview:recyclerview-selection:1.0.0'
}
//test
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
//google
dependencies {
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.google.firebase:firebase-core:17.2.1'
implementation 'com.google.firebase:firebase-analytics:17.2.1'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
implementation 'com.google.firebase:firebase-auth:19.2.0'
}
//3rd party
dependencies {
implementation 'com.jakewharton.timber:timber:4.7.1'
}
apply plugin: 'com.google.gms.google-services'
我做错了什么?我知道我可以使用 LayoutInflater.inflate 而不是 DatabindingUtil.inflate,但我以前使用这个流程没有问题。我有点像我在这里做的那样需要 viewDataBinding 对象供以后使用。
这在我的设备上运行正常。
你确定你的布局是正确的吗?在 onCreateView 中使用 layoutInflater.inflate(layoutResId, container, false)
检查它。如果有异常,则 DataBinding 无法扩充您的布局。
好的,所以我发现了问题。事实证明,即使您正确配置了几乎所有设置,您也可能 forget/miss 了解这个小信息。所以,我将在这里分享我学到的东西。
数据绑定布局文件略有不同,它们以 <layout>
的根标记开头,后跟数据元素和视图根元素。 如此处详细所述: Official Databinding Documentation
因此,用 <layout></layout>
包装所有布局将解决此异常。
例如:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
....
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
您必须将 xml 包裹在
中
<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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dark_blue"
tools:context=".ui.weather.WeatherFragment">
....../>
</layout>
我有一个 BaseFragment class:
abstract class BaseFragment: Fragment(), View.OnClickListener {
private lateinit var mBinding: ViewDataBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mBinding = DataBindingUtil.inflate<ViewDataBinding>(inflater, getLayoutId() , container, false)
return mBinding.root
}
abstract fun getLayoutId(): Int
abstract fun afterOnViewCreated()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
afterOnViewCreated()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
}
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
}
override fun onClick(v: View?) { }
fun getViewDataBinding(): ViewDataBinding {
return mBinding
}
fun setClickListener(vararg views: View) {
views.forEach { view -> view.setOnClickListener(this) }
}
}
我将其扩展以创建这样的新片段:
class HomeFragment : BaseFragment() {
private lateinit var homeViewModel: HomeViewModel
override fun getLayoutId(): Int {
return R.layout.fragment_home
}
override fun afterOnViewCreated() {
activity?.let{
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
}
//TODO:
}
}
但是,我遇到了这个崩溃:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mu.chatonymous, PID: 23328
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MainActivity}: java.lang.IllegalStateException: DataBindingUtil.inflate<…nt_home, container, false) must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3318)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3429)
at android.app.ActivityThread.-wrap12(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2009)
at android.os.Handler.dispatchMessage(Handler.java:109)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7555)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)
Caused by: java.lang.IllegalStateException: DataBindingUtil.inflate<…nt_home, container, false) must not be null
at com.mu.chatonymous.ui.base.BaseFragment.onCreateView(BaseFragment.kt:21)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2612)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:874)
at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2087)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1861)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1817)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1717)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2650)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2600)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2639)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:897)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1228)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1293)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2646)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2600)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:176)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1340)
at android.app.Activity.performStart(Activity.java:7364)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3281)
这是我的应用级别 build.gradle 文件:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'io.fabric'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.mu.chatonymous"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}
//androidx
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.lifecycle:lifecycle-runtime:2.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
kapt 'androidx.lifecycle:lifecycle-compiler:2.1.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
//for selection single or multiple items in recycler view
implementation 'androidx.recyclerview:recyclerview-selection:1.0.0'
}
//test
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
//google
dependencies {
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.google.firebase:firebase-core:17.2.1'
implementation 'com.google.firebase:firebase-analytics:17.2.1'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
implementation 'com.google.firebase:firebase-auth:19.2.0'
}
//3rd party
dependencies {
implementation 'com.jakewharton.timber:timber:4.7.1'
}
apply plugin: 'com.google.gms.google-services'
我做错了什么?我知道我可以使用 LayoutInflater.inflate 而不是 DatabindingUtil.inflate,但我以前使用这个流程没有问题。我有点像我在这里做的那样需要 viewDataBinding 对象供以后使用。
这在我的设备上运行正常。
你确定你的布局是正确的吗?在 onCreateView 中使用 layoutInflater.inflate(layoutResId, container, false)
检查它。如果有异常,则 DataBinding 无法扩充您的布局。
好的,所以我发现了问题。事实证明,即使您正确配置了几乎所有设置,您也可能 forget/miss 了解这个小信息。所以,我将在这里分享我学到的东西。
数据绑定布局文件略有不同,它们以 <layout>
的根标记开头,后跟数据元素和视图根元素。 如此处详细所述: Official Databinding Documentation
因此,用 <layout></layout>
包装所有布局将解决此异常。
例如:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
....
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
您必须将 xml 包裹在
中<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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dark_blue"
tools:context=".ui.weather.WeatherFragment">
....../>
</layout>