#java #android #arrays #kotlin
#java #Android #массивы #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
.
Но я не понимаю, почему, потому что в методе listener searchButton
я инициализирую каждый объект массива. Кто-нибудь знает, почему это происходит, и, возможно, что идет не так?
РЕДАКТИРОВАТЬ: создание ListMusicService
:
val listMusicService = ListMusicService(this, adapter)
Ответ №1:
Вы создаете новый объект MainActivity
val activity = MainActivity()
это просто пустой объект, вместо этого вам нужно передать this
в качестве экземпляра MainAcitiy
listMusic
метода to и использовать его.
ListMusicService
класс уже принимает context
объект, поэтому кажется, что вы передаете экземпляр activity (без кода об этом), используйте существующий экземпляр адаптера 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
}
Комментарии:
1. Ну, как именно мне нужно передать ее, чтобы я мог получить доступ к
SongInfo
массиву вListMusicService
2. @shuzo можете ли вы обновить свой пост о том, как вы создаете экземпляр
ListMusicService
класса, хотя я добавляю код решения в середине.3. @shuzo как и ожидалось, следуйте опубликованному коду и дайте мне знать.
4. Большое вам спасибо за вашу помощь. Теперь он работает полностью!
5. @shuzo С удовольствием. Ознакомьтесь с обновленным кодом. У класса MusicService уже есть адаптер, поэтому используйте его напрямую. Если вы не хотите создавать новый объект адаптера в mainactivity, вы можете даже удалить возвращаемый экземпляр адаптера и добавить
adapter.notifyDataSetChanged()
в концеlistMusic
метода.context.adapter
требуется только в том случае, если вы воссоздаете объект адаптераMainActivity
. Счастливого кодирования!