Reputation: 154
I use MVVM architecture in my project. When it first called, it works. but after that, it does not work. here is my code.
fun loadYgosuData() : LiveData<ArrayList<YgosuData>> {
Log.d(TAG, "loadYgosuData()...")
return liveData {
Log.d(TAG, "liveData Scope running....")
val element = withContext(Dispatchers.IO) {
Jsoup.connect("https://www.ygosu.com/community/real_article")
.get()
.select("div.board_wrap tbody tr")
}
emit(setYgosuData(element))
}
}
fun setYgosuData(tmpDoc: Elements?) : ArrayList<YgosuData> {
var tmpList = ArrayList<YgosuData>()
if (tmpDoc != null) {
//Log.d(TAG, "element : $tmpDoc")
for (e in tmpDoc) {
var title = e.select("td.tit a")
var name = e.select("td.name a")
var read = e.select("td.read")
var date = e.select("td.date")
var url = e.select("td.tit a").attr("href").toString()
var tmpYgosuData = YgosuData(
title = title.text(),
name = name.text(),
read = read.text(),
date = date.text(),
url = url
)
tmpList.add(tmpYgosuData)
}
}
Log.d(TAG, "여기2 ${tmpList.toString()}")
return tmpList
}
Could you help me please? Thank you.
Upvotes: 1
Views: 610
Reputation: 2732
From official doc
The liveData building block serves as a structured concurrency primitive between coroutines and LiveData. The code block starts executing when LiveData becomes active and is automatically canceled after a configurable timeout when the LiveData becomes inactive. If it is canceled before completion, it is restarted if the LiveData becomes active again. If it completed successfully in a previous run, it doesn't restart. Note that it is restarted only if canceled automatically. If the block is canceled for any other reason (e.g. throwing a CancelationException), it is not restarted.
That's why it works for the first time as you mentioned.
Solution1: combine liveData with Transformations
private val body: MutableLiveData<String> = MutableLiveData()
val YgousData = body.switchMap {
liveData {
Log.d(TAG, "liveData Scope running....")
val element = withContext(Dispatchers.IO) {
Jsoup.connect("https://www.ygosu.com/community/real_article")
.get()
.select("div.board_wrap tbody tr")
}
emit(setYgosuData(element))
}
}
fun callApi(param:String){
body.value = param
}
You can change the body
based on which you want to trigger api call
Solution2: You can do api call explicitly and then post the data to livedata (w/o using livedata builder)
Upvotes: 2