Sometime I feel that using AsyncTask is quite overkill for the task, I am looking for similar function like SwingUtilities.invokeLater in android. Because I just want to execute one line of code, no point to create a new class for that.
Maybe you're looking for:
Activity.runOnUiThread(Runnable action)
Activity.runOnUiThread(Runnable action);
The above method is slightly different than invokeLater of java because it checks if you are already on ui thread then it will run your Runnable immediately.
There is another way to make sure your Runnable gets called later and not immediately even if you are on UI thread. To do that you write following code while you are on the main thread.. if you call this when on backend thread your runnable will be exected on backend thread..
Handler h = new Handler();
h.post(new Runnable() {
#Override
public void run() {
//your code..
}
);
I don't remember exactly what invokeLater() does, but if you want to execute something delayed, you can use postDealayed(). That goes on the UI thread, so not fit for long running tasks, naturally.
Related
So, I am working in android studio and trying to set a pause between two methods. In the first one, a gif is loaded and in the second one a pop-up message appears. I've tried to use Thread.sleep and the TimeUnit as bellow but both of them execute in a way that the time is waited before running everything else. In another words, my code down bellow waits 4 seconds and then runs gameGif() and gameFinish() simultaneously. Here is my piece of code:
gameGif();
{
try
{
TimeUnit.SECONDS.sleep(4);
}
catch(InterruptedException ex)
{}
}
gameFinish();
This is working for me
gameGif();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
gameFinish();
}
}, 4000);
What you are doing is setting the intention to update the UI. The actual UI updates are performed by the Android Looper separate to your code. In fact, by calling wait(), you're actually blocking the rendering thread from doing its update.
Using a Handler is the correct way to do it, as Matus posts. The Handler will organise the scheduling with the Looper and will still allow the Looper to run (i.e. is non-blocking). When the timeout elapses it will call the Runnable
The one thing you need to be careful with this approach, is to call the Handler on the UI loop (i.e. from one of the 'normal' Android methods). If you call it from your own Thread it won't interact with the Looper correctly.
I was trying to implement a looping Runnable. The example I've found seems to use the following idea to kick-start the runnable.
handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
handler.postDelayed(this, 10000);
doIt();
count ++;
}
};
r.run();// what I prefer
// handler.postDelayed(r, 1000);//their idea
I prefer using the call to the run() method to start the Runnable. What would be the possible troubles that I could get into if any by a direct call to run()!
Thanks! :)
If you call r.run(), the Runnable will be executed immediately. But if you call handler.postDelayed(r, 1000); as they recommended, the Runnable will not be executed until 1s is past. So, this is the first point. Second, why don't you use the Thread Loop merchanism provided by Android, namely Handler AsyncTask HandlerThread for the sake that Android supports it very well?
I prefer using the call to the run() method to start the Runnable.
OK.
What would be the possible troubles that I could get into if any by a direct call to run()!
The first pass through run() would happen immediately, as opposed to your commented-out code, which would cause the first pass through run() to occur ~1000ms from now.
However, I would dump the Handler. postDelayed() is also a method on View, so just use some widget in your UI.
I'm refactoring some code that runs a multi-stage process. Each step is inside a nested java.awt.EventQueue.invokeLAter.... call. It looks a little like this:
import java.awt.EventQueue;
public class NestedInvokeLater {
/**
* #param args
*/
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
changeTabPanel();
copySomeFiles();
enableNextButton1();
upDateProgressBar(10);
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
readInFiles();
doSomethingToFiles();
upDateProgressBar(15);
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
doSomethingElse();
upDateProgressBar(100);
}
});
}
});
}
});
};
}
I am new enough at Java that I don't get the point of nesting these calls to add 'jobs' to the EDT, and I'm not 100% confident with fiddling with these calls either. I think I understand what the invokeLater call does, and what each step does. Please correct me if this understanding is wrong:
invokeLater is used to add some invocation to the list of jobs to be done in the Event Dispatch thread. Java then deals with when/how each invocation is done, ensuring that the EDT and in turn the GUI doesn't lock as it performs jobs 'in the background'.
Nesting these calls says to me that we should queue a set of jobs, one of which is to queue something, which will queue some jobs....one of which is to queue something. But the first inner invocation is only ever queued once the previous job is done. Everything occurs sequentially (this is in line of my understanding of the whole process), but I don't see why you would use nested requests to queue jobs to do so. I would have, if I was writing this from scratch, have simply created functions for each invocation and called them in turn.
I recognise, being only a novice at Java I am probably missing something huge that makes this nesting important. But there is no documentation of this, and no commenting in the code about the nesting.
What am I missing? What, if anything is the point in this code?
There is no point in doing so many nested invocations. It is based on a good intention, but it's badly implemented.
If you want to do this properly, use a SwingWorker.
The documentation of SwingWorker has a neat example of how you should implement performing several tasks in the background of the application (the PrimeNumbersTask class showed there).
Edit: Here's an example of what you should do with SwingWorker in your case.
class SequentialInvoker extends SwingWorker<Void, Integer> {
#Override
public void doInBackground() {
changeTabPanel();
copySomeFiles();
enableNextButton1();
setProgress(10);
readInFiles();
doSomethingToFiles();
setProgress(15);
doSomethingElse();
setProgress(100);
}
}
To actually show the progress on a progress bar, take a look at the following code, copied from the SwingWorker documentation:
JTextArea textArea = new JTextArea();
JProgressBar progressBar = new JProgressBar(0, 100);
SequentialInvoker task = new SequentialInvoker();
task.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
With this code, your progress bar will show the progress as the SwingWorker works.
One advantage of doing it this way is that other queued up things get to run in between. So, in between the section that does changeTabPanel() and the part that does readInFiles(), the GUI will get to respond to the user clicking on a button etc...
The actual implementation is a bit of a confusing mess and illustrates (IMHO) why anonymous functions were not such a good idea. Your inclination to make the three parts "real" functions and call them sequentially is a good one. But, to maintain the same logic, what you really need to do is make them three runnables and have each invokeLater the subsequent one.
And #Cyrille is correct that doing these major tasks on the EDT is poor practice.
There are three jobs that are used in invokeLater here. Each one does a costly thing, call updateProgressBar and then adds the next job to the EDT.
The thing is, if the code just continued to the next costly thing instead of calling invokeLater to do it, the EDT would not have the chance to repaint the progress bar to show the new value of it. This is probably why the work is broken in three invokelater calls.
Now, this is not what I would call a good code. This is pretty bad practice: one should not do a long process in the EDT because it blocks everything and makes the GUI unresponsive. This should be changed so that the process is done in a separate thread, and then only call invokeLater to update the progress bar.
Edit: To answer more generally the question in the title: there is almost never a sensible reason to nest calls to invokeLater. When you are doing this, you say "queue this job so that it is done in the same thread but later when you feel it would be good". So it gives a chance to the rest of the GUI to repaint itself, like here. But it only makes sense if you have a long running process in the EDT, which you should always avoid.
The code you posted makes absolutely no sense to me - you can just write everything sequentially because you have no parallel threads running which might post events on the EDT. You need the first invokeLater() though, as you use Swing components.
But as your code suggests you are doing some relatively lengthy operations: reading files, do something with them, ... You should run these methods in a new worker thread, NOT the EDT. And, in the run() method of these worker threads, you'll need a call to EventQueue.invokeLater() to have your GUI updated.
I have an animation in which triggers an event. This event fires a lot of computing usage and thus stutters the UI.
What I need to do is keep the thread running smoothly. When the event happens it will pass a string down to the thread, perform calculations (including using the audioRecord class) and return a boolean variable.
I have looked around and it seems AsyncTask may be the best solution, but I wanted to see if any of you had any ideas? Considering performance, Is this the best way to go?
Thanks,
Ben
Generally AsyncTask is fine.
But if you dont need to acess the UI thread for your background operation you can simply use a new thread.
new Thread(new Runnable() {
public void run() {
//do stuff
}
}).start();
I'm developing a small app, which would have Swing GUI. App is doing IO task in another thread, when that thread finishes GUI should be updated acordingly to reflect thread's operation result. Class running in a (worker, non-GUI) has object passed to it in contructor which would be used for updating GUI, so I don't need to put GUI stuff in a non-GUI class, but rather pass object for updating GUI to that class.
As I understand form reading here, (thread/swing) safe options for updating (changing) Swing GUI would be to use javax.swing.SwingUtilities.invokeLater(), javax.swing.SwingUtilities.invokeLaterWait() and/or javax.swing.SwingWorker() which basically are doing the same thing.
This all threading issue with Swing is a little confusing for me, and yet I need to use threads to do anything meaningful in GUI apps and not hung GUI while processing in EDT, so what interests me for now is this:
Are invokeLater and invokeLaterWait like sending message to EDT and waiting for it do it when it finishes processing messages that were before that call?
is it correct from Swing thread safety aspect, to do something like this:
interface IUPDATEGUI {
public void update();
}
// in EDT/where I can access components directly
class UpdateJList implements IUPDATEGUI {
public void update() {
// update JList...
someJList.revalidate();
someJList.repain();
}
}
class FileOperations implements Runnable {
private IUPDATEGUI upObj;
List<File> result = new ArrayList<File>; // upObject is accessing this
public void FileOperations(IUPDATEGUI upObj) {
this.upObj = upObj;
}
private void someIOTask() {
// ...
// IO processing finished, result is in "result"
}
public void run() {
someIOTask();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
upObj.update(); // access result and update JList
}
}; );
}
}
In case this isn't correct then how should this be done?
If I could, I would prefer to use invokeLater instead of SwingWorker if possible, because I wouldn't need to change my whole class and it's somehow more neat/distinct me (like sending a message in Win32 apps).
Thanks in advance.
Using invokeLater() and invokeAndWait() passes the Runnable parameter into the queue awaiting execution in the EDT. So calling invokeLater() will cause the Runnable to execute in the EDT when the EDT is able to process the request. invokeAndWait() simply waits (in the calling thread) until this execution takes place.
Using SwingWorker is ideal if you want to do background tasks that notify the EDT either at the end of execution or in intermediate states. An example would be to pass the current progress of a process to a JProgressBar.
For your example it seems that SwingWorker is a better choice but if you don't want to change your code too much then calling invokeLater() when the process is done will be just fine.
I'd recommend not using the invokeAndWait until java 7. I found a spurious wake-up on this method that can cause really painful bugs. For me it led to some really rare and hard to debug null pointer exceptions.
http://bugs.sun.com/view_bug.do?bug_id=6852111
It's fixed as of java 7 b77.
invokeLater is fine. This puts the call into the AWT event queue, so that it will get executed in the EDT in due course. Your program will continue running, and does not wait for your callable to get called.