Грузить данные во ViewModel нужно через AssistedInject (Hilt) или parametersOf (koin) и т.п. в подобных фреймворках в первичный конструктор ViewModel, а создание модели без данных, и загрузка их после создания - костыль, за который нужно бить по рукам)
Далее: 1 способ: loadInitialData имеет внутри launch - coroutineScope, и LaunchedEffect аналогично. Профит от launch { launch {} } буквально?
Далее: Грузить контакты, "Пользователь возвращается на экран "contacts_list" и видит удаленный контакт в списке, поскольку вьюмодель уже создана и init блок больше не отрабатывает." - Для таких ситуация существует Flow. Нужно брать из него данные в экране списка контактов и тогда там всегда будет актуальная информация. Конакты сохраняются в бд: если это Room, в нем можно возвращать тип Flow<List<T>>, а во viewModel и\или на экране подписываться с помощью Flow<List<T>>.collect {}. Тогда операции insert\delete\update будут выполняться штатно и без каких-либо дополнительных костылей
import com.google.gson.GsonBuilder
import com.google.gson.annotations.SerializedName
import okhttp3.ResponseBody
import retrofit2.Retrofit
import retrofit2.http.GET
data class ResponseWrapper(
@SerializedName("version") val version: String,
@SerializedName("reqId") val reqId: String,
@SerializedName("status") val status: String,
@SerializedName("sig") val sig: String,
@SerializedName("table") val table: Table
)
data class Table(
@SerializedName("cols") val cols: List<Column>,
@SerializedName("rows") val rows: List<Row>,
@SerializedName("parsedNumHeaders") val parsedNumHeaders: Int
)
data class Column(
@SerializedName("id") val id: String,
@SerializedName("label") val label: String,
@SerializedName("type") val type: String
)
data class Row(
@SerializedName("c") val cells: List<Cell?>
)
data class Cell(
@SerializedName("v") val value: String
)
interface GSheetsService {
@GET("gviz/tq?tqx=out:json")
suspend fun getSheetData(): ResponseBody
}
fun String.dataToJsonString(): String =
substringAfter("Query.setResponse(").let {
it.substring(0, it.lastIndex - 1)
}
fun String.getResponseFromJson(): ResponseWrapper =
GsonBuilder().setLenient().create()
.fromJson(this, ResponseWrapper::class.java)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val gSService = Retrofit.Builder()
.baseUrl(
"https://docs.google.com/spreadsheets/d/<ID документа>/"
).build().create(GSheetsService::class.java)
lifecycleScope.launch(Dispatchers.IO) {
val response = gSService.getSheetData().string().dataToJsonString().getResponseFromJson()
Log.d("response", "$response")
}
}
Ну и конечно же, я не говорю про разрешение на использование интернета)
Огромное спасибо за совет! Приму к сведению!
Грузить данные во ViewModel нужно через AssistedInject (Hilt) или parametersOf (koin) и т.п. в подобных фреймворках в первичный конструктор ViewModel, а создание модели без данных, и загрузка их после создания - костыль, за который нужно бить по рукам)
Далее: 1 способ:
loadInitialData
имеет внутри launch - coroutineScope, и LaunchedEffect аналогично. Профит от launch { launch {} } буквально?Далее: Грузить контакты, "Пользователь возвращается на экран
"contacts_list"
и видит удаленный контакт в списке, поскольку вьюмодель уже создана и init блок больше не отрабатывает." - Для таких ситуация существует Flow. Нужно брать из него данные в экране списка контактов и тогда там всегда будет актуальная информация. Конакты сохраняются в бд: если это Room, в нем можно возвращать тип Flow<List<T>>, а во viewModel и\или на экране подписываться с помощью Flow<List<T>>.collect {}. Тогда операции insert\delete\update будут выполняться штатно и без каких-либо дополнительных костылейБлагодарю за замечание! Проверил и обновил!
От обновлений не сбежишь, я всё равно тебя настигну😏😏😏
Благодарю за замечание, обновил!
Будет ли часть про хранение данных? Очень интересно!
Ну и конечно же, я не говорю про разрешение на использование интернета)
Да, сейчас проверил, дошел до 12000 строк, дальше надоело)
Строки размером по 8 столбцов