hi i want use jsoup to load a large table from html, what is the best way for doing this in async way?
AsyncTask? coroutines? doasync library? which one? i need show progressbar while fetching data so please tell me what is the best way?
UPDATE:
i want run this code in async
doc: Document = Jsoup.connect(url).timeout(0).maxBodySize(0).ignoreHttpErrors(true).sslSocketFactory(setTrustAllCerts()).get()
// some code for parsing...
In Kotlin, the general approach is coroutines, but normal threading is also a completely fine option, depending on what you're doing.
For example, if your operation is a thread-blocking operation, it actually can't run safely in a coroutine unless it's dispatched in a separate thread. For coroutines, you need to know the difference between suspending and blocking (huge difference).
So if reading the HTML table is a blocking operation, and you don't need to integrate with other coroutines, then a normal thread works just fine. There are many Java examples that are transferable to Kotlin.
With coroutines, you can do something like:
suspend fun getDoc() = withContext(Dispatchers.IO) {
Jsoup.connect(url).timeout(0).maxBodySize(0).ignoreHttpErrors(true).sslSocketFactory(setTrustAllCerts()).get()
}
Then, in your main code:
fun main() = runBlocking {
val deferredDoc = async { getDoc() }
// Do whatever.... it's not being blocked...
val doc = deferredDoc.await() // SUSPENDING CALL - but not blocking
}
Obviously, your program's structure will look different than this example, because it depends entirely on what code you want to execute asynchronously with "getDoc()".
For example, you can even have another coroutine that executes while "deferredDoc.await()" is suspending, without even creating another thread. That's the benefit of coroutines.
In the structure above, we have 3 guaranteed threads:
Main thread, which is always blocked
Main Coroutine thread. This is what the coroutines generally run on. Kotlin coroutines will run your coroutines asynchronously inside this thread using suspension.
IO thread. This is what your blocking code will run on.
I'll advice you try out Kotlin Coroutines. This would enable you dispatch expensive or long-running operations i.e. querying databases, making network requests/calls off to other threads thereby not blocking the Main Thread. Coroutines help you avoid the hassle of callbacks. Also, Google deprecated the AsyncTask API (in Android 11) and recommends using Java’s Concurrency framework or Kotlin Coroutines as the way to go for multi-threading purposes.
Related
I have read one article which says the following :
* Room will provide main-safety automatically if you use suspend functions, RxJava, or LiveData.
** Networking libraries such as Retrofit and Volley manage their own threads and do not require explicit main-safety in your code when used with Kotlin coroutines.
So I have two questions :
If i will have one suspend function inside viewmodel and it's having long running task inside it and it does not use any dispatcher. So if I will call this function from activity/fragment, then will it work as simple function as we have not defined any dispatcher and will block the ui ?
As stated above in the statements, for room/retrofit, should we use dispatcher explicitly(like IO in these cases) as they are taking care of background thread by themselves.
Googled it, did not get exact answer, so posting to get clarity.
Yes, the suspended function will run normally & will not block the UI unless you use a blocking coroutine like runBlocking or withContext that returns a value to the UI.
A simple launch i.e. viewModelScope.launch would not block a thread.
As per the docs they use a custom dispatcher to handle threading.
From the code-lab docs:
Both Room and Retrofit make suspending functions main-safe.
It's safe to call these suspend funs from Dispatchers.Main, even though they
fetch from the network and write to the database.
Both Room and Retrofit use a custom dispatcher and do not use
Dispatchers.IO.
Room will run coroutines using the default query and
transaction Executor that's configured.
Retrofit will create a new Call object under the hood, and call
enqueue on it to send the request asynchronously.
As my understand,
When you call suspend function, you need to provide a coroutine scope. So, if you provide Dispatcher.Main or MainScope, it will block UI.
Room/Retrofit has implicit coroutine scope. That means you don't need provide it for them. But when you call to Room/Retrofit, you will need to provide coroutine scope like [1]
I have a couple questions on kotlin coroutines.
how many thread could get involved when working with coroutines?
if we use just Dispatchers.Main, would only one thread get involved(single threaded)? if we use Dispatchers.IO, would multiple thread possibly get involved (maximum of 64 threads)?
what will be the use case for using Dispatchers.Main? most articles that I have read say all UI related works should present in Dispatchers.Main and background related works(like reading/writing data from/to database, network requests) needs to present in Dispatchers.IO but I don't understand what UI related works present in Dispatchers.Main since UI related work don't really necessary need coroutines (with Dispatchers.Main)
we use susepnd fuction with coroutines for some works that could block the current thread. For example, read data from disk, network requests, or high tense computation etc. if these works are executed by suspend function, what/who is in charge when these functions are suspended? I think something has to be working on these suspend functions anyway. will that be background threads that is in charge of below?
reading/writing data from/to databse
waiting for network request
computing high tense computation
please point out if my wording or questions are incorrect.
Thank you in advance.
I think you answered yourself. Short answer is: Dispatchers.Main - single thread, Dispatchers.Default - number of cores, Dispatchers.IO - at most 64. You can read about it here. Full answer is a little more complicated as limits could be reconfigured, they may differ on different platforms (e.g. JavaScript is always single-threaded), Default partially shares threads with IO, etc. We can also create our own thread pools.
I'm not sure what do you mean. Coroutines are generally never necessary in order to do anything. But if we use coroutines inside UI application, then we should use Dispatchers.Main for UI-related stuff.
We should almost never use blocking code inside coroutines (one exception is Dispatchers.IO). If we do that, the coroutine won't suspend, but just block, possibly making other parts of our application unresponsive or degrading the performance.
I have been working with coroutines for few weeks and sometimes its tough to understand the real working difference between thread concurrency and coroutine concurrency.
How suspend functions works internally ? How is continuation block helping in resuming the computation after suspension.
How is sequential computation of the line of code inside coroutine not blocking the thread ? and how is it better than thread concurrency ?
How suspend functions works internally?
Briefly, on the Java platform a suspend fun compiles into bytecode that is dramatically different from a plain function. It receives a hidden extra parameter (the continuation), creates its own continuation object, and the entire body of the function is implemented (approximately) as a big switch statement that allows the function to jump into the middle of the body when resuming.
When a suspend fun suspends, the underlying Java method actually returns. The return value is a special COROUTINE_SUSPENDED singleton object which the framework knows how to interpret. It is the responsibility of the suspend fun itself to save the continuation object where it will be accessible when the result of the function is ready.
The official documentation has a good in-depth description of these details.
How is continuation block helping in resuming the computation after suspension.
This is related to what I said above, that the suspend fun itself is responsible for ensuring it gets resumed later on. It must do that inside the block provided by the function suspendCoroutineOrReturn. User code doesn't call it directly, but the more high-level analogs suspendCoroutine and suspendCancellableCoroutine. These take over the concern of resuming the coroutine on the appropriate thread and the developer is responsible only for ensuring that continuation.resume() is called with the result when it becomes available. This typically happens in a callback you pass to an async call.
You can study this answer that tries to explain the suspend-resume mechanism in a self-contained example.
How is sequential computation of the line of code inside coroutine not blocking the thread?
Because it actually compiles into returning from the function and later on resuming by jumping into the middle of the function body.
and how is it better than thread concurrency?
Native threads are heavyweight resources that take time to create and destroy. Coroutines are much lighter-weight and consequently you can start many more of them, and more quickly.
The internal workings are explained in the original design document https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md which has a section on "Implementation Details".
I'm trying to implement start syncing process while app comes foreground.
I want to make multiple API call in the background thread, Which one will be better approach for this scenario Kotlin Coroutines or ThreadPool executor
I have tried with Kotlin Coroutines, but it seems like it try to execute all functions call in parallel which cause some Lag in APP initial times. is there a best approach to execute multiple functions in parallel
of course, Kotlin Coroutines, because coroutines aren't necessarily bound to any particular thread. A coroutine can start executing in one thread, suspend execution, and resume on a different thread. Coroutines aren't managed by the operating system. They're managed at the user space level by the Kotlin Runtime.
Kotlin Co-routines are the way to go.
Why? :
They are cheap.
Increases code readability.
Configuration setup is less (as compared to RxJava) for simple tasks.
try this
viewModelScope.launch{
val function1Async=async{ function1()}
val function2Async=async{function2()
function1Async.await()
function2Async.await()
}
If the alternative is to use ThreadPools, then you should use coroutines. They are built to make this easier. Also, you would save some memory since you would be sharing threads with other processes.
If what you need is a single thread that's continuously running in the background. Then maybe a thread is the way to go to ensure it's execution is not interrupted by a pending coroutine. Although an isolated single threaded dispatcher should solve this problem (if you have it).
You mentioned experiencing lag? Was this lag averted when you used a threadpool? If this is an issue, then fire the coroutines from another coroutine. :)
Hi I am reading about rxjava2 which is basically for async operations. I found it has an operator concept which AsyncTask in android does not.
How else is rxjava2 different than AsyncTask?
RxJava is not "basically for async operation". That is only one aspect of it.
RxJava allows you to compose operations on data, such that the output of one operation can be used as the input to the next. This operates similarly to streams implementations.
RxJava uses this composability to allow some operations to occur in a multi-threaded environment. It does this by providing well-defined semantics for the operators when working with multiple schedulers. RxJava can use asyncTask to perform some operations.
RxJava manages back pressure requirements for some applications by using Flowable chains, while Observable chains have no back pressure requirements. The former is appropriate where buffering is required or explicit acknowledgment of dropped information needs to be made.
RxJava has clear error and error handling semantics.
asyncTask just handles asynchronous tasks.
AsyncTask is Android’s default tool for developers needing to do some simple long-ish running work in the context of a UI screen without blocking the UI.
The main problem with AsyncTask is:
MULTIPLE WEB SERVICE CALLS:
To solve this in AsyncTask create an inner AsyncTask subclass in our Activity/Fragment, perform the network operation in the background, and take the result of that operation and update the UI in the main thread.
this approach has some issues and limitations:
Memory/context leaks are easily created is an inner class and thus holds an implicit reference to the outer class Also, what if we want to chain another long operation after the network call? We’d have to nest two AsyncTasks which can significantly reduce readability.
ERROR HANDLING
What happens if something goes wrong? Unfortunately, there’s no out-of-the-box solution for this.
And other problem like device rotation, back press handle etc.
To solved this all problem look at RxJava
Handle Error using RxJava is like this:
webService.doSomething(someData)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
result -> resultText.setText("It worked!"),
e -> handleError(e));
Second, In multiple web services call.
public Observable<List<Weather>> getWeatherForLargeUsCapitals() {
return cityDirectory.getUsCapitals()
.flatMap(cityList -> Observable.from(cityList))
.filter(city -> city.getPopulation() > 500,000)
.flatMap(city -> weatherService.getCurrentWeather(city)) //each runs in parallel
.toSortedList((cw1,cw2) -> cw1.getCityName().compare(cw2.getCityName()));
}
Hope this may help you!!