绑定变量为空。如何让UI中的观察者等到查询的Livedata从数据库中执行?

Binding variable is null.. How to let the observer in UI wait till the queried Livedata is excuted from database?

我正在尝试从数据库中获取数据,然后将其以片段形式绑定到 XML。 所以我有存储库将数据从数据库获取到 ViewModel,UI 片段正在观察结果,然后将数据绑定到 XML。 但问题是应用程序正在崩溃,说数据为空,即使我正在取消观察者中的空数据。

我已经尝试在后台线程上执行查询,它似乎在返回数据(照片)时正常工作。

我认为问题在于查询需要时间,片段中的 Observer 没有等到查询完成。 所以查询没问题,我完全按照 Google 示例进行操作,但无法找出问题所在。 提前致谢。

_PhotoRepository

    class PhotoRepository @Inject constructor(
private val photoDao: PhotoDoa
) {

fun loadPhotoById(photoId: Int): LiveData<Photo> {
//        var photo: Photo? = null 
//        this is working and i am getting the photo object
//        appExecutors.diskIO().execute { 
                photo = photoDao.getObjectPhotoById(photoId)
           } 

    return photoDao.getPhotoById(photoId)
 }

}

_PhotoViewModel

class PhotoViewModel @Inject constructor(private val photoRepository: 
             PhotoRepository) :
ViewModel() {

private var _photoId = MutableLiveData<Int>()
val photoId: LiveData<Int>
    get() = _photoId


val photo: LiveData<Photo> = Transformations
    .switchMap(_photoId) { id ->
        photoRepository.loadPhotoById(id)
    }


fun setId(photoId: Int) {
 //        if (_photoId.value == photoId){
 //            return
 //        }
    _photoId.value = photoId

  }

 }

_PhotoFragment

class PhotoFragment : Fragment(), Injectable {

@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory

var binding by autoCleared<FragmentPhotoBinding>()

lateinit var photoViewModel: PhotoViewModel

 var photo = Photo()


override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

     binding = DataBindingUtil.inflate<FragmentPhotoBinding>(
        inflater,
        R.layout.fragment_photo,
        container,
        false
    )

    return binding.root

}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val params = PhotoFragmentArgs.fromBundle(arguments!!)

    photoViewModel = ViewModelProviders.of(
        this,
        viewModelFactory).get(PhotoViewModel::class.java)

    photoViewModel.setId(params.photoId)
   // photoViewModel.photo.removeObservers(viewLifecycleOwner)
    photoViewModel.photo.observe(viewLifecycleOwner, Observer {

        if (it != null) {
            binding.photo = it
        }

    })
  }
}

_Doa中的查询class

@Query(" SELECT * FROM Photo WHERE id = :id")
 abstract fun getPhotoById ( id: Int): LiveData<Photo>

_fragment_photo.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">

<data>

    <import type="com.mustafa.pixabayapp.models.Photo"/>
    <variable
        name="photo"
        type="Photo"/>

    <import type="com.mustafa.pixabayapp.utils.StringUtils" />
</data>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/photo_fragment_image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:imageUrl="@{photo.webFormatURL}"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@color/colorTransparentDark"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:id="@+id/photo_fragment_tags"
            style="@style/PixabayImageTextUser"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{StringUtils.getTags(photo.tags)}"
            tools:text="TEST - TEST - TEST"/>

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/photo_fragment_user_name"
                style="@style/PixabayImageTextUser"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentStart="true"
                android:text="@{StringUtils.byUser(photo.userName)}"
                tools:text="By: Mustafa"/>

            <TextView
                android:id="@+id/photo_fragment_comments"
                style="@style/PixabayImageTextUser"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_marginEnd="4dp"
                android:drawableStart="@drawable/ic_comment"

  android:text="@{StringUtils.getCommentsAsString(photo.commentsCount)}"
                tools:text="2222"/>

            <TextView
                android:id="@+id/photo_fragment_favorites"
                style="@style/PixabayImageTextUser"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="4dp"
                android:layout_toStartOf="@id/photo_fragment_comments"
                android:drawableStart="@drawable/ic_favorite"


 android:text="@{StringUtils.getFavoritesAsString(photo.favoritesCount)}"
                tools:text="2222"/>

            <TextView
                android:id="@+id/photo_fragment_likes"
                style="@style/PixabayImageTextUser"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="4dp"
                android:layout_toStartOf="@id/photo_fragment_favorites"
                android:drawableStart="@drawable/ic_like"

   android:text="@{StringUtils.getLikesAsString(photo.likesCount)}"
                tools:text="2222"/>
        </RelativeLayout>
    </LinearLayout>
</RelativeLayout>
</layout>

_错误信息:

 java.lang.IllegalArgumentException:
 Parameter specified as non-null is null: 
 method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter 
 userName at com.mustafa.pixabayapp.utils.StringUtils.byUser(Unknown 
 Source:2)at com.mustafa.pixabayapp.databinding.FragmentPhotoBindingImpl.
 executeBindings(FragmentPhotoBindingImpl.java:138)

是的,您对 "it takes time" 的假设是正确的。布局想要在其绑定后立即绘制一些东西,此时 photo 尚未加载。 您可以处理 StringUtils.byUser() 中的空值或在布局中添加空值检查,如下所示: