Wait for another method to execute..then continue - java

Actually a basic Java question which I did not come along when I was learning this programming language.
For best understanding my question I will provide a simple sample:
block of code {
-new AsynTask..
-some code which I want to execute after AsyncTask finishes executing..
}
I know I can put the second line of code in postExcecute in AsyncTask object. But is it possible for program flow to continue after AsyncTask is finished executing?

You don't want to do this. This totally destroys the purpose of using an AsyncTask- it will halt the original thread until the task is done, preventing it from doing other things. If you wanted to do that, you'd be better off without the task. Instead, you should put the code you want to execute after the task is done in the onPostExecute method of the AsyncTask.

Related

How do I make a android AsyncTask loading spinner while doInBackgroung()

I got an AsyncTask for URL connection. Now I want to have a loading spinner everytime I do the URL connection. I display the loading spinner in onPreExecute() and dismiss it in onPostExecute.
I tested this with an endless while loop in doInBackgroung().
The big problem is the GUI is freezing and the loading spinner is not shown.
In my opinion the reason is URLconnection.execute().get(). But I need the get() because the activity need the result to working with it.
My question is now: What is the best way to do this to achieve my wishes? (By the way it is not important to get a solution with an "AsyncTask solution" because there are maybe better solutions and AsyncTask will be deprecated with SDK version 30)
Thank you very much and stay healthy!
As you said AsyncTask will be deprecated.
So it is better to go for an alternative.
Since you mentioned you are not relying on AsyncTask, I will present to you another approach.
Let me introduce you to coroutines and convince you that they will solve your problem and "get the job done".
When I got to know about coroutines, this video was one of the first example that has demonstrated to me the potential of using coroutines in my app. At that point I was still using 100% Java, probably like you are right now.
The good part is: getting started with Kotlin is really easy! Not only you can call Kotlin functions from Java Code, you can also call Java functions from Kotlin code.
To "do something in background" in Kotlin, all you need to do is to launch a coroutine (on a background thread).
Do you have a ViewModel to fetch your data? If it is an option to transfer this file to kotlin, then starting (and scoping) a coroutine becomes as simple as this.
For fragments or activitities you could use other copes as well. However, using the global scope is usually discouraged.
Executing coroutines is as simple as that:
class MyViewModel: ViewModel() {
fun loadDataInBackgroundAndShowSpinner {
viewModelScope.launch {
// Coroutine that will be canceled when the ViewModel is cleared.
// start your spinning
// do all the heave data work on a background thread
doInBackground()
// end your spinning here
}
}
suspend fun doInBackground(inputURL: String) {
withContext(Dispatchers.IO) {
// Execute all your data fetching here
...
// Assign your data to your viewModel variables, post it to a LiveData object, etc.
}
}
}
You do not need any loops in the main thread or anything. By using withContext on a background thread you can achieve main-safety.
Within a launched coroutine, everything (by default) gets executed in order.
Still you will not block the Main Thread. How did you achieve that?
The key here is that your doInBackground function has the suspend keyword. Therefore your loadDataInBackgroundAndShowSpinner on the main thread will "suspend" your doInBackground function and the main thread is able to do whatever you want (i.e. nothing freezes). Then, once your doInBackground is finished, it will resume execution and you can just dismiss your spinner again on the main thread.
Kotlin coroutines make it so much easier to do something in the background and I really want to encourage you to give it a try! It will definitely solve your problem and I can not think of a more easy way.
Google also tried to make it as easy as possible to get you started when coming from Java.

How to show a loading-animation in javafx-application?

I just try to show a loading-animation while I access an ERP in my code like this:
protected void submit()
{
messageField.getStyleClass().add("smallLoading");
submitImpl();
messageField.getStyleClass().remove("smallLoading");
}
Sadly the animation is never shown... Just the result as before. I tried using Platform.runLater, which yielded the same result. I also transfered the last 2 lines in a Thread, which worked (the animation was shown), but lead to the error "Not on FX application thread", when the Submitter tried to write to my message-field. When I passed the Thread to Platform.runLater it did not show the animation... I googled a little bit, but could not find a solution. Maybe I'm missing something important...
I appreciate any help. Thank you!
It seems like you don't really fully understand how the UI thread works.
The code you've posted is single-threaded. It all operates on the UI thread. You add a style class, do some work, then remove it. The problem is that this sequence of operations is effectively "atomic": the UI doesn't actually update anything until its all done. This is why you don't see the loading symbol change.
When you put all of this within runLater the result is the same. It's still all on the UI thread. The only difference here is that rather than running the code now, you're deferring it until some point "later" (probably actually very soon).
When you try to put the last two lines in a separate thread, the issue is that you're trying to make UI changes on a non-UI thread. That's not allowed.
What you want to do is run everything on a non-UI thread, and push back the UI operations to the UI thread with runLater. Something like this:
new Thread(() -> {
Platform.runLater(()-> messageField.getStyleClass().add("smallLoading"));
submitImpl();
Platform.runLater(()-> messageField.getStyleClass().remove("smallLoading"));
}).start();

Is chaining AsyncTasks considered bad practice? [duplicate]

This question already has answers here:
Android AsyncTask - Order of execution
(6 answers)
Closed 7 years ago.
I'm writing an app that does the following:
Parses a webpage and extracts image URLs from it
Decodes them to Bitmap and shows them in an ImageView
I don't want these to run on the UI thread and obviously the 2nd point can't be performed without the 1st being completed.
Can i chain AsyncTasks to achieve this? I mean starting the second one from the first one's onPostExecute() method.
Is this considered bad practice? If so, how should i do this?
(this is a theoretical question, i'm not asking for code)
You can definitely do that and there is nothing wrong with chaining multiple AsyncTasks if you really have to. And I want to emphasise: only if you really have to.
AsyncTasks bring a certain overhead with them. If you chain two AsyncTasks you get twice the overhead. You don't want that. You should use the least amount of AsyncTasks possible.
In your case the solution actually seems quite simple: Perform all of the work in just one AsyncTask. Ask yourself: Is there really any need for two separate AsyncTasks? From your description it certainly doesn't seem like it. If you just use one AsyncTask your code will run a lot more efficiently than if you use two.
Please note that AsyncTasks should only be used for short operations that take a few seconds and which are started in response to a user action. If you need to perform some long running operation in the background than an AsyncTask is probably not the best solution. I can't really tell from your description if what you want to do is something suited for an AsyncTask or not, but if the work you are doing doesn't fall into the criteria I described above you are probably better of with an alternative solution.
Can i chain AsyncTasks to achieve this? I mean starting the second one
from the first one's onPostExecute() method
The only constraint is that the AsyncTask has to be instantiated on the UI Thread. As long as you instantiate it on the UI Thread you should be safe. So the answer is yes, you can do it.
If so, how should i do this?
There are different approaches to solve the same problem. You could use an ExecutorService for instance, and a Delegate/Listener, an Observer or a BroadcastReceiver to notify the completeness of a task
There's a good answer for this here but since you're asking theoretically, I'll tag an opinion onto the end of it.
From the AsyncTask docs:
AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.
Chaining of Futures (or Promises) is a perfectly normal asynchronous practice. Future A does something and returns a value; this value can then be consumed by another asynchronous chunk of code, and so on, forming a logical processing chain.
In pseudo-code, it looks like this:
Future( calculate and return x).map( consume x and return y)
.map ( consume y and so on)
Of course, you can. Theoretically, this logic you talked about above can't be wrong. But, you have to understand that: onPreExecute and onPostExecute are called on the Main Thread, namely the UI Thread while doInBackground on another non-main-thread. Meanwhile, if you executed the second AsyncTask on the doInBackground of the 1st one, onPreExecute and onPostExecute of the 2nd one wound not be run on the Main Thread. Take notice of that.
Well, I don't think it is bad practice. The only downside I can see is that code becomes a little more difficult to read, especially if you end up chaining a lot of callbacks.

JavaFX - Task/Background processing - How to call multiple methods in a task?

I'm trying to teach myself JavaFX and stumbled over a problem I can't seem to fully understand even after reading anything remotely related I could find.
What I'm trying to do :
I basically want to run some quick processing in the background of my JavaFX application so to not block the UI for the user. While this is happening a UI element is put up which then should be removed as soon as the background process is finished.
So what I attempted to do was to just move those method calls into a Task which should then run without making the UI freeze.
Task task = new Task<Void>() {
#Override
protected Void call() {
step1();
step2();
step3();
}};
new Thread(task).start();
I want to call multiple methods of the class we're currently in, but what's happening instead is that only the first method gets invoked. It seems to me that after step1 has reached it's end it doesn't actually "return" to the Task. I've tried looking up how this works and what I could do but honestly didn't get any smarter. Basically all examples of threading and workers only included how to loop and do recurring things but I really just want a "single execution" but in background.
It's probably a really idiotic thing I'm trying to do and shows my little understanding of this but if anyone could point me into the right direction I'd be very thankful.
Thanks a lot!
Solution :
When working with JavaFX the use of "Platform.runLater(task)" is advisable since a normal Thread cannot interact with the UI. A IllegalStateException will be thrown and the thread is halted/canceled(?). The Task itself can remain unchanged but has to be handed to the Platform to execute it to prevent this issue. I changed that one line and everything was perfect afterwards.
I hope this might help someone, someday :-)

Eclipse suspend a specific thread while letting others run

Is there a way for the debugger to pause a specific thread while letting the other ones run? I want to verify some locks I have are working properly and Im not sure how to induce certain conditions. Note that all the threads run through the same code, so any changes to the code will affect all threads, where as I only want to stop one thread.
You might want to look at testing frameworks like MultithreadedTC - which lets you programmatically control flow through the different threads during the test so you can cause race conditions and timeouts during testing.
If you have a convenient point in your code to set a breakpoint for that single thread, you can change the Suspend Policy of that breakpoint in its properties to only stop the current thread instead of the whole VM.
You can add a method to do a sleep in the thread. Then you can call that method with junit or a simple POJO.
I was able to sort of fix my own problem by basically putting the following code in the thread code -
if(Thread.currentThread.getName()="thread1"){
Thread.currentThread.sleep(5000);
}
This way only thread 1 sleeps. It worked well enough that I saw my locks working, but this isnt really a good solution I feel. Perhaps someone can make something better?

Categories

Resources