Je suis en train de faire une appli qui obtient la (pseudo) valeurs de latence en faisant une demande à certaines url et l'enregistrement de combien de temps cela va prendre.
Tout d'abord, j'utilise de rénovation pour obtenir une réponse JSON à partir d'un serveur web. Cette réponse contient: le nom de l'hôte (par exemple Ebay royaume-UNI), l'url de l'hôte (par ex. www.ebay.co.uk), et une url de l'image. J'ai une carte de cette réponse sur ma classe de données qui se présente comme suit:
data class(
val name: String,
var url: String,
val icon: String,
var averagePing: Long = -1
)
l'url est une var propriété avant de faire les appels pour obtenir les valeurs de latence, j'ai besoin d'ajouter https:// dans le but de faire la demande.
Je suis en train de faire tout cela de la sorte:
fun getHostsLiveData() {
viewModelScope.launch(Dispatchers.IO) {
val hostList = repo.getHosts()
for (host in hostList) {
host.url = "https://" + host.url
host.averagePing = -1
}
hostListLiveData.postValue(hostList)//updated the recyclerview with initial values
//with default (-1) value of averagePing
for (host in hostList) {
async { pingHostAndUpdate(host.url, hostList) }
}
}
}
La première boucle for prépare mes données. La ligne après la boucle for soumet les données pour le recycleur adaptateur, afin d'afficher le nom d'hôte, l'adresse url et l'icône tout de suite (ça fonctionne c'est à dire que j'ai un travail d'observateur pour la LiveData), alors que je suis en attente pour les valeurs de latence.
La deuxième boucle for appelle la fonction pour calculer les valeurs de latence pour chaque hôte et le updateHostList() de la fonction de mises à jour de la LiveData.
C'est la façon dont les fonctions d'oeil:
suspend fun pingHostAndUpdate(url: String, hostList: MutableList<Host>) {
try {
val before = Calendar.getInstance().timeInMillis
val connection = URL(url).openConnection() as HttpURLConnection //Need error handling
connection.connectTimeout = 5*1000
connection.connect()
val after = Calendar.getInstance().timeInMillis
connection.disconnect()
val diff = after - before
updateHostList(url, diff, hostList)
} catch (e: MalformedURLException) {
Log.e("MalformedURLExceptionTAG", "MalformedURLException")
} catch (e: IOException) {
Log.e("IOExceptionTAG", "IOException")
}
}
fun updateHostList(url: String, pingResult: Long, hostList: MutableList<Host>) {
//All this on mainThread
var foundHost: Host? = null
var index = 0
for (host in hostListLiveData.value!!) {
if (host.url == url) {
foundHost = host
break
}
index++
}
if (foundHost != null) {
viewModelScope.launch(Dispatchers.Main) {
val host = Host(foundHost.name, foundHost.url, foundHost.icon, pingResult)
Log.d("TAAAG", "$host")
hostList[index] = host
hostListLiveData.value = hostList
}
}
}
L'ensemble de ce qui se passe dans le viewModel. Actuellement, je suis à jour de ma liste en soumettant l'ensemble de la liste de nouveau lorsque je modifie une propriété d'un élément de la liste, ce qui semble horrible pour moi.
Ma question est: Comment puis-je mettre à jour une seule propriété de l'hôte et de l'avoir de rafraîchissement de l'INTERFACE utilisateur automatiquement?
Merci d'avance
Edit: Mon observateur ressemble à ceci:
viewModel.hostListLiveData.observe(this, Observer { adapter.updateData(it) })
Et updateData() ressemble à ceci:
fun updateData(freshHostList: List<Host>) {
hostList.clear()
hostList.addAll(freshHostList)
notifyDataSetChanged()
}
@ArpitShukla, croyez-vous que j'aurais 2 fonctions de mise à jour? l'un pour l'affichage de la liste initiale et une autre pour la mise à jour sur l'élément de la liste? Ou aurais-je simplement mettre les deux notifyDataSetChanged() et notifyItemChanged() dans updateData()?
Edit2: changé mon appel de fonction pour la rendre asynchrone.