Lateinit variable not initialized error but got initialized (android)

huangapple go评论74阅读模式
英文:

Lateinit variable not initialized error but got initialized (android)

问题

我知道这听起来很奇怪。
所以在我的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)
英文:

I know that sounds weird.
So in my MainActivity am declaring an Array of the object SongInfo which looks like this:

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

This is how I am declaring the Array in my MainActivity:

lateinit var songInfo: Array&lt;SongInfo?&gt;

So, now when I press a button, the listener of this button executes this:

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

            songInfo = arrayOfNulls(cursor!!.count)

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

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

The ListMusicService class looks like this:

class ListMusicService(val context: Context, private var adapter: ArrayAdapter&lt;Any&gt;) {

    private val tag = &quot;MusicShare/ListMusicService&quot;

    fun listMusic(cursor: Cursor): ArrayAdapter&lt;Any&gt; {
        val activity = MainActivity()
        adapter.clear()

        val songInfo = arrayOfNulls&lt;SongInfo&gt;(cursor.count)

        var duration: Double

        var index = 0

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

            adapter.add(cursor.getString(3) + &quot;: &quot; + cursor.getString(2) + &quot; (&quot; + duration + &quot;)&quot;)

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

            Log.d(tag, &quot;searchMusic: writing songInfo&quot;)

            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
    }
}

Pressing the searchButton now causes a kotlin.UninitializedPropertyAccessException: lateinit property songInfo has not been initialized.
But I don't understand why because in the listener method of searchButton I'm initializing every object of the array. Does anybody know why this happens and maybe what goes wrong?

EDIT: Creating the ListMusicService:

val listMusicService = ListMusicService(this, adapter)

答案1

得分: 1

你正在创建一个新的 MainActivity 对象:

val activity = MainActivity()

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

ListMusicService 类已经接受一个 context 对象,所以看起来你正将活动的实例传递给了它(没有相关的代码),你应该使用 MainActivity 的现有适配器实例。

// 在主活动的某处
val listMusicService = ListMusicService(this, adapter)

// 在 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
}
英文:

You are creating a new object of MainActivity

val activity = MainActivity()

which is just an empty object, instead you need to pass this as an instance of MainAcitiy to listMusic method and use it.


ListMusicService class already taking a context object so seems like you are passing the activity's instance (no code about it), use the existing adapter instance of MainAcitivty.

// somewhere in main activity 
val listMusicService = ListMusicService(this, adapter)

// inside searchButton.setOnClickListener
adapter = listMusicService.listMusic(cursor)
adapter.notifyDataSetChanged()

In ListMusicService

fun listMusic(cursor: Cursor): ArrayAdapter&lt;Any&gt; {
    adapter.clear()
    val songInfo = arrayOfNulls&lt;SongInfo&gt;(cursor.count)

    var duration: Double

    var index = 0

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

        adapter.add(cursor.getString(3) + &quot;: &quot; + cursor.getString(2) + &quot; (&quot; + duration + &quot;)&quot;)

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

        Log.d(tag, &quot;searchMusic: writing songInfo&quot;)

        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
}

huangapple
  • 本文由 发表于 2020年9月20日 04:55:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/63973310.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定