我正在尝试通过在获取远程数据之前将本地数据返回到UI来实现第一个离线应用程序。
这是我的代码
存储库
val trip: LiveData<DomainTrip> = Transformations.map(database.tripDao.getTrip(tripId)) {
it.asDomainModel()
}
suspend fun refreshTrip(token: String) {
withContext(Dispatchers.IO) {
val trip = webservice.getTrip(tripId, "Bearer $token").await()
database.tripDao.insertAll(trip.asDatabaseModel())
}
}
DAO
interface TripDao {
@Query("select * from databasetrip WHERE _id = :id")
fun getTrip(id: String): LiveData<DatabaseTrip>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(trip: DatabaseTrip)
}
ViewModel
private val tripRepository = TripRepository(getDatabase(application), tripId)
var trip = tripRepository.trip
如果用户打开的行程已经存储在数据库中,则上面的代码可以正常工作。用户打开该行后,就会立即调用it.asDomainModel()
。从远程检索到该行程并将其保存到数据库后,it.asDomainModel()
再次被调用。
我的问题是,如果用户打开的旅程不在数据库中,则第一次调用it.asDomainModel()
时,上面的代码会崩溃,并且it
上的空指针异常。
更让我感到困惑的是,如果上面的代码被应用到这个dao查询中
@Query("select * from databasetripinfo")
fun getTrips(): LiveData<List<DatabaseTripInfo>>
即使我的数据库为空,我在两次it.asDomainModel()
调用中都不会得到任何空指针异常。
有人可以帮我吗?当数据库没有该记录时,如何避免在it.asDomainModel()
上出现空指针异常?
thx
答案 0 :(得分:1)
一切正常。如果没有具有给定ID的项目,则实时数据将返回null。您可以在转换(it?.asDomainModel
)中进行映射之前检查是否为空
但是对于列表,您将得到一个空列表而不是null(这是一个惯例)。