Следуйте моим простым шагам, чтобы решить вашу проблему,
Шаг 1: Проверьте один раз CustomApplication
имя указано или отсутствует в AndroidManifest.xml
,
<application
android:name=".CustomApplication"
в противном случае вы получите эту проблему
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication/com.example.myapplication.AddressActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.example.myapplication.CustomApplication
Шаг 2: Проверьте уровень вашего модуля build.gradle
файл
примените эти изменения
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
проверить зависимости - для Kotlin используйте kapt вместо annotationProcessor
implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
в противном случае вы получите эту проблему
java.lang.RuntimeException: cannot find implementation for com.example.myapplication.Database. Database_Impl does not exist
Шаг 3: проверьте свой AddressDao
интерфейс, добавьте эту функцию
@Delete
suspend fun deleteAddress(address: Address)
Шаг 4:
в классе AddressAdapter
добавьте этого слушателя,
interface ItemListener {
fun onItemClicked(address: Address, position: Int)
}
добавьте переменную слушателя и функцию setListener
private lateinit var listener: ItemListener
interface ItemListener {
fun onItemClicked(address: Address, position: Int)
}
fun setListener(listener: ItemListener) {
this.listener = listener;
}
затем обновите свой код в методе tvDelete.setOnClickListener
viewHolder.tvDelete.setOnClickListener(View.OnClickListener { view ->
mItemManger.removeShownLayouts(viewHolder.swipelayout)
addresses.removeAt(position)
listener.onItemClicked(fl, position)
notifyDataSetChanged()
// notifyItemRemoved(position)
// notifyItemRangeChanged(position, addresses.size)
mItemManger.closeAllItems()
Toast.makeText(
view.context,
"Deleted " + viewHolder.tv.getText().toString(),
Toast.LENGTH_SHORT
).show()
})
Шаг 5: В классе AddressActivity
внесите эти изменения
Реализуйте здесь слушателя,
class AddressActivity : AppCompatActivity(), AddressAdapter.ItemListener {
затем переопределите метод
override fun onItemClicked(address: Address, position: Int) {
}
затем установите слушатель для адаптера
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = adapter
adapter.setListener(this)
затем обновите co de в методе переопределения
override fun onItemClicked(address: Address, position: Int) {
lifecycleScope.launch {
val application = application as CustomApplication
application.database.AddressDao().deleteAddress(address)
}
}
здесь я использовал сопрограмму, в противном случае вы также можете использовать AsycTask
для сопрограммы, добавьте эти зависимости в свой модуль build.gradle
файл
implementation "android.arch.lifecycle:extensions:1.1.1"
kapt "android.arch.lifecycle:compiler:1.1.1"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
если вы напрямую вызвали метод deleteAddress в классе пользовательского интерфейса, вы получите эту проблему
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
, поэтому используйте такие методы в фоновом потоке,
Если вы действительно хотите выполнить в основном потоке пользовательского интерфейса, сделайте это изменения в вашем коде
в интерфейсе AddressDao
,
@Delete
fun deleteAddress(address: Address)
в CustomApplication
классе, добавьте allowMainThreadQueries()
class CustomApplication : Application() {
lateinit var database: Database
private set
lateinit var addressDao: AddressDao
private set
override fun onCreate() {
super.onCreate()
this.database = Room.databaseBuilder<Database>(
applicationContext,
Database::class.java, "database"
).allowMainThreadQueries().build()
addressDao = database.AddressDao()
}
}