我正在使用 Kotlin 學習,并且我已經好幾天無法解決錯誤,所以我尋求幫助。
我正在嘗試從房間資料庫中檢索資料并將其放入變數(產品串列)中,但出現如下錯誤。
kotlin.UninitializedPropertyAccessException:lateinit 屬性 productList 尚未初始化
這是我的源代碼。我已經檢查了房間資料庫是否正常包含資料。
我想將從 db 中獲取的資料放入 productList 變數中并使用它。
提前致謝!
[MainActivity.kt]
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var PACKAGE_NAME: String
private var currentPosition: Int = 0
private var lastPosition: Int = 0
private lateinit var db: AppDatabase
private lateinit var productDao: ProductDao
private lateinit var productList: List<ProductEntity>
private var urls: String = ""
private var titles: String = ""
private var descs: String = ""
private var isVideos: String = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
db = AppDatabase.getInstance(this)!!
productDao = db.getProductDao()
setVideoItem()
}
private fun setVideoItem() {
val videosViewPager = binding.viewPagerVideos
val videoItems: MutableList<VideoItem> = ArrayList()
val files = File(this@MainActivity.filesDir, "products").listFiles()
Thread {
productList = productDao.getAll()
}.start()
for (i in productList) { //I want to store accessed data to productList variable
urls = "${i.idx}:"
titles = "${i.name}:"
descs = "${i.price}:"
}
println("urls:$urls")
println("titles:$titles")
println("descs:$descs")
}
[ProductDao.kt]
@Dao
interface ProductDao {
@Query("select * from ProductEntity")
fun getAll() : List<ProductEntity>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(product: ProductEntity)
@Query("select idx, name, price from ProductEntity where idx like :searchIdx")
fun searchProductByIdx(searchIdx: String) : ProductEntity
}
uj5u.com熱心網友回復:
productDao.getAll()
在需要時間執行的單獨執行緒上呼叫。所以你試圖productList
在執行緒初始化它之前訪問它。
這是執行緒總是丟失的競爭條件。
重新定位用于執行緒的代碼productList
應該可以解決這個問題:
Thread {
productList = productDao.getAll()
for (i in productList) {
urls = "${i.idx}:"
titles = "${i.name}:"
descs = "${i.price}:"
}
println("urls:$urls")
println("titles:$titles")
println("descs:$descs")
}.start()
uj5u.com熱心網友回復:
Thread {
productList = productDao.getAll()
}.start()
產品串列是在并行行程中的執行緒中獲取的,因此由于根據程式控制在線時它不是同步的,for (i in productList)
因此產品串列尚未初始化。您必須決定如何處理這種并發。要么同步呼叫該方法,要么在迭代后通過某種方法填充串列,或者在同一個執行緒中執行。
就像是
Thread {
productList = productDao.getAll()
//iterate through the list
//print the values
}.start()
uj5u.com熱心網友回復:
啟動一個執行緒訪問db,需要一些時間。主執行緒不會等待訪問資料庫的執行緒完成,所以此時讀取productList是未初始化的。
您可以在加載完成后訪問串列,或者在加載完成后Android Handler
用于通知主執行緒更新。
Thread {
productList = productDao.getAll()
for (i in productList) {
urls = "${i.idx}:"
titles = "${i.name}:"
descs = "${i.price}:"
}
println("urls:$urls")
println("titles:$titles")
println("descs:$descs")
}.start()
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/454449.html