【问题标题】:Lateinit variable not initialized error but got initialized (android)Lateinit 变量未初始化错误但已初始化(android)
【发布时间】:2020-09-19 20:55:11
【问题描述】:

我知道这听起来很奇怪。 因此,在我的 MainActivity 中,我声明了一个对象数组 SongInfo,如下所示:

class SongInfo {
    lateinit var title: String
    lateinit var contentId: String
    lateinit var filepath: String
}

这就是我在 MainActivity 中声明数组的方式:

lateinit var songInfo: Array<SongInfo?>

所以,现在当我按下一个按钮时,这个按钮的监听器会执行这个:

searchButton.setOnClickListener {
            val cursor = contentResolver.query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                arrayOf(
                    "_id",
                    "_data",
                    MediaStore.Audio.Media.TITLE,
                    MediaStore.Audio.Media.ARTIST,
                    MediaStore.Audio.Media.DURATION
                ),
                "is_music == 1",
                null, null
            )

            songInfo = arrayOfNulls(cursor!!.count)

            for (index in songInfo.indices) {
                songInfo[index] = SongInfo()
                Log.d(tag, "searchButton: $index")
            }

            adapter = listMusicService.listMusic(cursor)
            adapter.notifyDataSetChanged()
        }

ListMusicService 类如下所示:

class ListMusicService(val context: Context, private var adapter: ArrayAdapter<Any>) {

    private val tag = "MusicShare/ListMusicService"

    fun listMusic(cursor: Cursor): ArrayAdapter<Any> {
        val activity = MainActivity()
        adapter.clear()

        val songInfo = arrayOfNulls<SongInfo>(cursor.count)

        var duration: Double

        var index = 0

        while (cursor.moveToNext()) {
            duration = ((cursor.getDouble(4) / 600).roundToInt() / 100).toDouble()

            adapter.add(cursor.getString(3) + ": " + cursor.getString(2) + " (" + duration + ")")

            val filepath = File(cursor.getString(1))

            Log.d(tag, "searchMusic: writing songInfo")

            songInfo[index] = SongInfo()

            songInfo[index]!!.title = filepath.name
            songInfo[index]!!.filepath = filepath.absolutePath
            activity.songInfo[index]!!.filepath = filepath.absolutePath
            songInfo[index]!!.contentId = cursor.getString(0)

            index++
        }

        return adapter
    }
}

现在按下searchButton 会导致kotlin.UninitializedPropertyAccessException: lateinit property songInfo has not been initialized。 但我不明白为什么,因为在searchButton 的侦听器方法中,我正在初始化数组的每个对象。有谁知道为什么会发生这种情况以及可能出了什么问题?

编辑:创建ListMusicService:

val listMusicService = ListMusicService(this, adapter)

【问题讨论】:

    标签: java android arrays kotlin


    【解决方案1】:

    您正在创建MainActivity 的新对象

    val activity = MainActivity()
    

    这只是一个空对象,您需要将this 作为MainAcitiy 的实例传递给listMusic 方法并使用它。


    ListMusicService 类已经采用了一个context 对象,所以您似乎正在传递活动的实例(没有关于它的代码),请使用MainAcitivty 的现有适配器实例。

    // somewhere in main activity 
    val listMusicService = ListMusicService(this, adapter)
    
    // inside searchButton.setOnClickListener
    adapter = listMusicService.listMusic(cursor)
    adapter.notifyDataSetChanged()
    

    在列表音乐服务中

    fun listMusic(cursor: Cursor): ArrayAdapter<Any> {
        adapter.clear()
        val songInfo = arrayOfNulls<SongInfo>(cursor.count)
    
        var duration: Double
    
        var index = 0
    
        while (cursor.moveToNext()) {
            duration = ((cursor.getDouble(4) / 600).roundToInt() / 100).toDouble()
    
            adapter.add(cursor.getString(3) + ": " + cursor.getString(2) + " (" + duration + ")")
    
            val filepath = File(cursor.getString(1))
    
            Log.d(tag, "searchMusic: writing songInfo")
    
            songInfo[index] = SongInfo()
    
            songInfo[index]!!.title = filepath.name
            songInfo[index]!!.filepath = filepath.absolutePath
            activity.songInfo[index]!!.filepath = filepath.absolutePath
            songInfo[index]!!.contentId = cursor.getString(0)
    
            index++
        }
        return adapter
    }
    

    【讨论】:

    • 那么我究竟需要如何传递它才能访问ListMusicService 中的SongInfo 数组
    • @shuzo 你能更新你的帖子吗,关于你如何创建ListMusicService 类的实例,虽然我在中间添加了解决方案代码。
    • @shuzo 正如所料,按照发布的代码,让我知道。
    • 非常感谢您的帮助。它现在完全可以工作了!
    • @shuzo 我很高兴。请检查更新的代码。 MusicService 类已经有了适配器,所以直接使用它。如果您不想在 mainactivity 中创建适配器的新对象,那么您甚至可以删除返回适配器实例并在 listMusic 方法的末尾添加 adapter.notifyDataSetChanged()。仅当您在 MainActivity 中重新创建适配器对象时,才需要 context.adapter。编码快乐!
    猜你喜欢
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    相关资源
    最近更新 更多