Новый объект из класса данных .copy () - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть класс данных в Котлине:

data class myDataClass(
    var a: ArrayList<Long> = ArrayList(),
    var b: ArrayList<Long> = ArrayList(),
    var c: ArrayList<Long> = ArrayList(),
    ...
)

private val myDataClassVal: myDataClass = myDataClass()

Я использую этот класс данных для хранения данных, полученных с помощью BLE, которые, когда каждый ArrayList имеет определенную длину, отправляют в API REST. После этого POST данные в myDataClass будут .clear() ed, и процесс повторится.

Часть приложения BLE чувствительна ко времени, и каждый POST занимает примерно 1 секунду; мое решение для этого состоит в том, чтобы запустить мою функцию POST асинхронно; в отличие от запуска в том же потоке, что и код BLE. Я делаю это следующим образом:

GlobalScope.async { 
    uploadData(myDataClassVal) 
}

myDataClassVal.a.clear()
myDataClassVal.b.clear()
myDataClassVal.c.clear()

К сожалению, когда я очищаю данные в myDataClass сразу после вызова функции async, данные на самом деле очищаются от класса данных перед их сериализацией и POST-обработкой.

В попытке решить эту проблему я создал дубликат myDataClass прямо перед загрузкой и передал его в функцию async загрузки. дубликат создается с использованием функции .copy(), как описано здесь :

uploadBuffer = myDataClassVal.copy()
GlobalScope.async {
    uploadData(uploadBuffer)
}
myDataClassVal.a.clear()
....

Однако uploadBuffer все еще полностью пуст. Если я создаю копию myDataClass таким же образом и POST в том же потоке:

uploadBuffer = myDataClassVal.copy()
uploadData(uploadBuffer)
myDataClassVal.a.clear()
....

Тогда все работает просто отлично.

Итак, я думаю, что моя проблема в том, что uploadBuffer это просто указатель на myDataClass. Если это так, то как мне создать новый объект, дубликат myDataClass для использования в моем async POST?

Спасибо, Адам

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Почему бы просто не создать новый экземпляр для каждого нового запуска. Вам не понадобится функция copy, просто создайте новый экземпляр после запуска:

GlobalScope.launch {
    uploadData(uploadBuffer)
}
uploadBuffer = new myDataClassVal()

КСТАТИ: Вы должны начать занятия с заглавной буквы, например, MyDataClassVal. См. Соглашения об именах: https://kotlinlang.org/docs/reference/coding-conventions.html#naming-rulesan

Вы должны использовать launch вместо async, потому что вам не нужен результат, см. Kotlin Async vs Launch

0 голосов
/ 07 ноября 2018

Если вы хотите очистить данные только после завершения асинхронной задачи, вы можете попробовать использовать await.

 uploadBuffer = myDataClassVal.copy()
 GlobalScope.async {
     uploadData(uploadBuffer)
 }.await()
 myDataClassVal.a.clear() //this will execute after async returns
 ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...