Lateinit变量未初始化错误,但已初始化(android)

时间:2020-09-19 20:55:11

标签: java android arrays kotlin

我知道这听起来很奇怪。 因此,在我的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)

1 个答案:

答案 0 :(得分: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()

在ListMusicService中

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
}