0

我正在开发一个非常简单的示例应用程序,它使用 ViewModel、协程和数据绑定。

这里使用了非常简单的类:

class MainFragment : Fragment() {

    companion object {
        fun newInstance() = MainFragment()
    }

    private val viewModel by viewModels<MainViewModel>()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val binding: MainFragmentBinding =
            DataBindingUtil.inflate(inflater, R.layout.main_fragment, container, false)
        binding.lifecycleOwner = viewLifecycleOwner
        binding.model = viewModel
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewModel.loadData()
    }
}
class MainViewModel : ViewModel() {

    val txt1 = MutableLiveData<String>()

    val txt2 = Transformations.map(txt1)
    {
        if (it == "test") R.string.yes else R.string.no
    }


    fun loadData() {
        viewModelScope.launch(Dispatchers.IO)
        {
            delay(1000)
            txt1.postValue("test")
        }
    }

}
<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <variable
            name="model"
            type="com.example.myapplication.ui.main.MainViewModel" />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
        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"
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.main.MainFragment">

        <TextView
            android:id="@+id/txt1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{model.txt1}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

        <TextView
            android:id="@+id/txt2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{model.txt2}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

不幸的是,这个非常简单的应用程序因以下堆栈跟踪而崩溃:

    java.lang.RuntimeException: Failed to call observer method
        at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:226)
        at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeMethodsForEvent(ClassesInfoCache.java:194)
        at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeCallbacks(ClassesInfoCache.java:185)
        at androidx.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:37)
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
        at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
        at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
        at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
        at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
        at androidx.fragment.app.FragmentViewLifecycleOwner.handleLifecycleEvent(FragmentViewLifecycleOwner.java:51)
        at androidx.fragment.app.Fragment.performStart(Fragment.java:2737)
        at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:355)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1192)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354)
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2617)
        at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2575)
        at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:258)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:550)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
        at android.app.Activity.performStart(Activity.java:7157)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2937)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x0
        at android.content.res.Resources.getText(Resources.java:348)
        at android.widget.TextView.setText(TextView.java:5831)
        at com.example.myapplication.databinding.MainFragmentBindingImpl.executeBindings(MainFragmentBindingImpl.java:168)
        at androidx.databinding.ViewDataBinding.executeBindingsInternal(ViewDataBinding.java:472)
        at androidx.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:444)
        at androidx.databinding.ViewDataBinding$OnStartListener.onStart(ViewDataBinding.java:1685)
        at java.lang.reflect.Method.invoke(Native Method)
        at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:216)
        at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeMethodsForEvent(ClassesInfoCache.java:194) 
        at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeCallbacks(ClassesInfoCache.java:185) 
        at androidx.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:37) 
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361) 
        at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300) 
        at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339) 
        at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145) 
        at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131) 
        at androidx.fragment.app.FragmentViewLifecycleOwner.handleLifecycleEvent(FragmentViewLifecycleOwner.java:51) 
        at androidx.fragment.app.Fragment.performStart(Fragment.java:2737) 
        at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:355) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1192) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354) 
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495) 
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2617) 
        at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2575) 
        at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:258) 
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:550) 
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178) 
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391) 
        at android.app.Activity.performStart(Activity.java:7157) 
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2937) 
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180) 
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 

MainFragmentBindingImpl.java该类的第 168 行如下:

this.txt2.setText(androidxDatabindingViewDataBindingSafeUnboxModelTxt2GetValue);

所以,问题是Transformations.map(...). 如果我删除txt2属性的绑定,一切正常。

我怎样才能避免这个错误?

谢谢您的帮助。

4

1 回答 1

0

设置一个接受资源 id的@BindingAdapterfor 。android:text我认为它试图将整数初始值设置为 0,因此ResourceNotFound. 在您的适配器中检查这一点。字符串资源 id 的值立即从 0 变为正确的值。

@JvmStatic
@BindingAdapter("android:text")
fun setTextResource(view: TextView, @StringRes resource: Int) {
    Timber.d("resource id: $resource")
    if (resource == 0) {
        view.text = ""
    } else {
        view.setText(resource)
    }
}
于 2021-01-14T15:41:38.687 回答