Android 如何删除LiveData<;对象>;在活动中使用Room和LiveData?
我正在使用Kotlin和Android架构组件(LiveData和Room)制作一个Android应用程序 我有一个显示用户的活动(存储在数据库中,并使用带有ViewModel的查询进行恢复) 我必须具有编辑或删除当前用户的选项。问题是,当我尝试删除用户时,应用程序崩溃,但当我再次打开它时,用户消失了 这是我的全班代码:Android 如何删除LiveData<;对象>;在活动中使用Room和LiveData?,android,kotlin,android-room,android-architecture-components,android-livedata,Android,Kotlin,Android Room,Android Architecture Components,Android Livedata,我正在使用Kotlin和Android架构组件(LiveData和Room)制作一个Android应用程序 我有一个显示用户的活动(存储在数据库中,并使用带有ViewModel的查询进行恢复) 我必须具有编辑或删除当前用户的选项。问题是,当我尝试删除用户时,应用程序崩溃,但当我再次打开它时,用户消失了 这是我的全班代码: class DetallesPerfilActivity : AppCompatActivity() { private var user_id : Int = -1 lat
class DetallesPerfilActivity : AppCompatActivity() {
private var user_id : Int = -1
lateinit var usuarioViewModel: UsuarioViewModel
private lateinit var usuarioActual : Usuario
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detalles_perfil)
toolbar.title = getString(R.string.detalle_usuario)
setSupportActionBar(toolbar)
val ab = supportActionBar
ab!!.setDisplayHomeAsUpEnabled(true)
user_id = intent.getIntExtra("USER_ID", -1)
usuarioViewModel = ViewModelProviders.of(this).get(UsuarioViewModel::class.java)
usuarioViewModel.getUsuario(user_id).observe(this, Observer {
usuarioActual = it!!
populateUserFieldsFromDB()
})
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_edit,menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when(item?.itemId){
android.R.id.home ->{
onBackPressed()
return true
}
R.id.edit_item ->{
val builder = AlertDialog.Builder(this@DetallesPerfilActivity)
builder.setItems(R.array.dialogo_editar_eliminar){
dialog, which ->
when(which){
0-> {
val nav = Intent(this@DetallesPerfilActivity, RegistrarUsuarioActivity::class.java)
nav.putExtra("USER_ID", user_id)
startActivityForResult(nav,349)
}
1 -> {
val innerBuilder = AlertDialog.Builder(this@DetallesPerfilActivity)
innerBuilder.setTitle(getString(R.string.eliminar_usuario))
.setMessage(getString(R.string.esta_seguro_que_desea_eliminar_usuario))
.setPositiveButton(getString(R.string.si)){
dialog, id ->
deleteUser()
}
.setNegativeButton(getString(R.string.no)){
dialog, id ->
}
val innerDialog = innerBuilder.create()
innerDialog.show()
}
}
}
val dialog = builder.create()
dialog.show()
return true
}
}
return super.onOptionsItemSelected(item)
}
private fun populateUserFieldsFromDB(){
NombreApellidosUsuarioTV.text = "${usuarioActual.nombre} ${usuarioActual.apellidos}"
GeneroUsuarioTV.text = usuarioActual.genero
EdadUsuarioTV.text = usuarioActual.edad.toString()
}
private fun deleteUser(){
usuarioViewModel.delete(usuarioActual)
Toast.makeText(this@DetallesPerfilActivity,getString(R.string.usuario_eliminado_correctamente),Toast.LENGTH_SHORT).show()
finish()
}
}
我得到的错误是在日志中:
2019-01-10 22:29:09.573 2984-3066/? E/WindowManager: win=Window{6686c65 u0 com.kps.spart.moskimedicationreminder/com.kps.spart.moskimedicationreminder.MainActivity EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=false win.mRemoveOnExit=false win.mViewVisibility=8, caller=com.android.server.wm.AppWindowToken.destroySurfaces:748 com.android.server.wm.AppWindowToken.destroySurfaces:732 com.android.server.wm.WindowState.onExitAnimationDone:5523 com.android.server.wm.AppWindowAnimator.stepAnimationLocked:517 com.android.server.wm.AppWindowToken.stepAppWindowsAnimation:1745
2019-01-10 22:29:12.443 1269-1269/com.kps.spart.moskimedicationreminder E/ViewRootImpl: sendUserActionEvent() returned.
2019-01-10 22:29:12.465 2984-3066/? E/WindowManager: win=Window{667c3c2 u0 com.kps.spart.moskimedicationreminder/com.kps.spart.moskimedicationreminder.DetallesPerfilActivity EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=true win.mRemoveOnExit=true win.mViewVisibility=0, caller=com.android.server.wm.AppWindowToken.destroySurfaces:748 com.android.server.wm.AppWindowToken.destroySurfaces:732 com.android.server.wm.WindowState.onExitAnimationDone:5523 com.android.server.wm.WindowStateAnimator.stepAnimationLocked:553 com.android.server.wm.DisplayContent.lambda$-com_android_server_wm_DisplayContent_21292:465
2019-01-10 22:29:13.591 1269-1269/com.kps.spart.moskimedicationreminder E/ViewRootImpl: sendUserActionEvent() returned.
2019-01-10 22:29:13.634 1269-1269/com.kps.spart.moskimedicationreminder E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.kps.spart.moskimedicationreminder, PID: 1269
kotlin.KotlinNullPointerException
at com.kps.spart.moskimedicationreminder.DetallesPerfilActivity$onCreate$1.onChanged(DetallesPerfilActivity.kt:43)
at com.kps.spart.moskimedicationreminder.DetallesPerfilActivity$onCreate$1.onChanged(DetallesPerfilActivity.kt:23)
at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
at android.arch.lifecycle.LiveData.setValue(LiveData.java:282)
at android.arch.lifecycle.LiveData$1.run(LiveData.java:87)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
2019-01-10 22:29:13.732 1958-1958/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2019-01-10 22:29:14.519 4660-4799/? E/PBSessionCacheImpl: sessionId[20496443867522706] not persisted.
2019-01-10 22:29:15.547 2984-3636/? E/Watchdog: !@Sync 1101 [2019-01-10 22:29:15.547]
2019-01-10 22:29:34.739 2027-2027/? E/FeatureClassSet: [#CMH#] Rubin package not supported
2019-01-10 22:29:43.943 6319-6637/? E/BtGatt.GattService: [GSIM LOG]: gsimLogHandler, msg: MESSAGE_SCAN_START, appName: com.google.uid.shared, scannerId: 4, reportDelayMillis=0
2019-01-10 22:29:44.619 2052-2052/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2019-01-10 22:29:45.540 3655-3695/? E/RequestManager_FLP: [LocationManagerService] Location remove 552b5a4 from system
2019-01-10 22:29:45.554 2984-3636/? E/Watchdog: !@Sync 1102 [2019-01-10 22:29:45.554]
2019-01-10 22:29:45.896 6319-6637/? E/BtGatt.GattService: [GSIM LOG]: gsimLogHandler, msg: MESSAGE_SCAN_STOP, appName: com.google.uid.shared, scannerId: 4, reportDelayMillis=0
2019-01-10 22:29:54.628 2081-2081/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2019-01-10 22:29:54.963 2081-2081/? E/zygote: The String#value field is not present on Android versions >= 6.0
2019-01-10 22:29:55.147 2081-2081/? E/TTS: Unparsable line in file with voice data checksums: voices-list.dev/signature.sf 7846532c8eb3d4d374813dae6d74638b
2019-01-10 22:29:55.147 2081-2081/? E/TTS: Unparsable line in file with voice data checksums: voices-list.dev/voices-list-dsig.pb c1024b1416240bb24b316bac696f5cdb
2019-01-10 22:29:55.148 2081-2081/? E/TTS: Unparsable line in file with voice data checksums: voices-list.rel/signature.sf 93ee1641133be6e6d8cb83934833cd8c
2019-01-10 22:29:55.148 2081-2081/? E/TTS: Unparsable line in file with voice data checksums: voices-list.rel/voices-list-rsig.pb 8ad16260ab46941c146c4598d78862ee
2019-01-10 22:29:55.574 2081-2107/? E/native: compressed_store.h:386 Read: Failed to read compressed states.
2019-01-10 22:30:13.464 3531-3531/? E/KeyguardFingerPrint: updateFingerprintListeningState#mFingerprintRunningState=0 shouldListenForFingerprint=true
2019-01-10 22:30:13.464 3531-3531/? E/KeyguardFingerPrint: startListeningForFingerprint()
因此,如何使用ViewModel删除LiveData对象而不使应用程序崩溃?一种简单的方法是对观察到的值添加空检查
usuarioViewModel.getUsuario(user_id).observe(this, Observer {
if(it!=null){
usuarioActual = it
populateUserFieldsFromDB()
}
})
因此,我终于找到了这个问题的解决方案,当我用usuarioViewModel删除usuario时产生了错误,观察者得到了一个空引用,为了解决这个问题,我需要删除LiveData的观察者,然后删除用户 首先,我保留对当前LiveData的引用:
usuarioViewModel = ViewModelProviders.of(this).get(UsuarioViewModel::class.java)
usuarioActualLive = usuarioViewModel.getUsuario(user_id)
usuarioActualLive.observe(this, Observer {
populateUserFieldsFromDB(it)
})
因此,当我想删除当前用户时,我会使用以下方法删除匿名观察者:
private fun deleteUser(){
if(usuarioActualLive.hasObservers()){
usuarioActualLive.removeObservers(this@DetallesPerfilActivity)
usuarioViewModel.delete(usuarioActualLive.value!!)
finish()
}
}
我使用数据绑定,爱德华多·科罗纳的解决方案对我不起作用。最后,我使用转换来避免直接观察b
var note:LiveData<Note> = Transformations.map(_note){it?:Note()}
var-note:LiveData=Transformations.map(_-note){it?:note()}
顺便问一下,你所说的BD是什么意思?用room制作的SQLite BD,并使用usuarioViewModel进行查询。这就是我要问的。BD的完整形式是什么?D最可能代表数据库。但是B代表什么呢?顺便问一下,我已经回答了你的问题。请看一看。对不起,这是一个打字错误(我感到羞耻),它是数据库,它是非常有用的。非常感谢。