Here is my code:
retrofit2.Call<User> call = MainActivity.apiInterface.performUserLogin (username,password);
Log.d(TAG,"retrofit");
call.enqueue (new Callback<User> () {
#Override
public void onResponse( retrofit2.Call<User> call, Response<User> response )
{
Log.d (TAG,"in");
if(response.body ().getResponse ().equals ("ok"))
{
Log.d (TAG,"ok");
MainActivity.prefConfig.writeLoginStatus (true);
loginFormActivityLisener.performLogin (response.body ().getName ());
}
else if(response.body ().getResponse ().equals ("failed"))
{
MainActivity.prefConfig.displayToast ("Login Failed... Please try again...");
Log.d(TAG,"failed");
}
}
#Override
public void onFailure( retrofit2.Call<User> call, Throwable t ) {
}
});
I have question, why call.enqueue is not working? It is like it wasnt there. Its do nothing.
enqueue() function of Retrofit works asynchronously. It is a background task and runs the request on a background thread. If you debug your code, you will most probably see debugger skips the enqueue call and continues to execute next line. When background thread finishes, after skipping a few more lines maybe, it gets back to call.enqueue().
If you want to use a foreground task, you can choose execute() function, or there are other implementations to wait main thread until callback responses, like using events (see EventBus library).
Related
I have method in class MyClassB which is triggered asynchronously from a method of MyClassA:
public void getProductCall()
{
new Thread(new Runnable() {
#Override
public void run() {
try {
productRequest = service.createS4ProductRequest(getRepriceItems());
//Below is a rest call to another system
String response = pricing.getS4ProductResponse(quote.getAssetQuoteNrAndVrsn(), productRequest);
//I'm using the below 2 lines to check from ClassA's method to see if this process has ended
setProductResponse(response);
productPriceProcessEnded=true;
} catch (Exception e) {
productPriceErrorOccured=true;
e.printStackTrace();
}
}
}).start();
}
This is the piece of code in MyClassA i used to check if the above method is complete.
for(int i=0;i<1000000000;i++)
{
if(!networkAsynCalls.isListPriceErrorOccured())
{
if(networkAsynCalls.isListPriceprocessEnded())
{
return networkAsynCalls.getListReponse();
}
else
{
Thread.sleep(250);
continue;
}
}
else
return null;
}
instead of using this random for loop can i use some inbuilt method or service pool or something ?
Because,
1) This thread on method is in another class
2) In class MyClassB i have few more methods like this, so i need to check the status of all the methods in MyClassA
Thanks for any help.
If I undestand what you're trying to do is dispatch some code to be ran asynchronously, then be able to wait until it is completed (successfully or failed). If that's the case, you should take a look at Futures.
Here is an example based on the Javadoc:
FutureTask<String> future =
new FutureTask<String>(new Callable<String>() {
public String call() {
// do stuff
return "result";
}});
This code creates an object "future" that can be invoked to execute searcher.search(target). At this point, the code is not executed at all. You simply have an object representing a computation that may be executed asynchronously. To do so, you'd call:
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(future);
This snippet created an Executor (which is a fixed pool of 5 threads), then handed over the future to it for execution. The executor will run the computation from Future asynchronously.
Future offers some methods (see the Javadoc) to wait until completion, cancel, check completion status, etc. For example,
String result = future.get();
will block, waiting for the result indefinitely. A get(10, TimeUnit.SECONDS) will wait for 10 seconds and if the future has not completed, throw.
Need to confirm something. The following code:
CompletableFuture
.supplyAsync(() -> {return doSomethingAndReturnA();})
.thenApply(a -> convertToB(a));
would be the same as:
CompletableFuture
.supplyAsync(() -> {
A a = doSomethingAndReturnA();
convertToB(a);
});
Right?
Furthermore, another two questions following as for "is there any reason why we would use thenApply?"
1) having big code for conversion?
or
2) need to reuse the lambda block in other places?
It is not the same thing. In the second example where thenApply is not used it is certain that the call to convertToB is executed in the same thread as the method doSomethingAndReturnA.
But, in the first example when the thenApply method is used other things can happen.
First of all, if the CompletableFuture that executes the doSomethingAndReturnA has completed, the invocation of the thenApply will happen in the caller thread. If the CompletableFutures hasn't been completed the Function passed to thenApply will be invoked in the same thread as doSomethingAndReturnA.
Confusing? Well this article might be helpful (thanks #SotiriosDelimanolis for the link).
I have provided a short example that illustrates how thenApply works.
public class CompletableTest {
public static void main(String... args) throws ExecutionException, InterruptedException {
final CompletableFuture<Integer> future = CompletableFuture
.supplyAsync(() -> doSomethingAndReturnA())
.thenApply(a -> convertToB(a));
future.get();
}
private static int convertToB(final String a) {
System.out.println("convertToB: " + Thread.currentThread().getName());
return Integer.parseInt(a);
}
private static String doSomethingAndReturnA() {
System.out.println("doSomethingAndReturnA: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "1";
}
}
And the output is:
doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1
convertToB: ForkJoinPool.commonPool-worker-1
So, when the first operation is slow (i.e. the CompletableFuture is not yet completed) both calls occur in the same thread. But if the we were to remove the Thread.sleep-call from the doSomethingAndReturnA the output (may) be like this:
doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1
convertToB: main
Note that convertToB call is in the main thread.
thenApply() is a callback function, which will be executed when supplyAsync() return a value.
In code snippet 2, the thread which invoked doSomethingAndReturnA() waits for the function to get executed and return the data.
But in some exceptional cases (like making Webservice call and waiting for response), the thread has to wait for long time to get the response, which badly consumes lot of system computation resources (just waiting for response).
To avoid that, CompletableFuture comes with callback feature, where once the doSomethingAndReturnA() is invoked, a separate thread will take care of executing doSomethingAndReturnA() and the main caller thread will continue to do other operations without waiting for the response to return.
Once the response of doSomethingAndReturnA is available, the call back method will be invoked (i.e., thenApply())
I have a problem while working with JavaFX and Threads. Basically I have two options: working with Tasks or Platform.runLater. As I understand Platform.runLater should be used for simple/short tasks, and Task for the longer ones. However, I cannot use any of them.
When I call Thread, it has to pop up a captcha dialog in a middle of task. While using Task, it ignores my request to show new dialog... It does not let me to create a new stage.
On the other hand, when I use Platform.runLater, it lets me show a dialog, however, the program's main window freezes until the pop up dialog is showed.
I need any kind of solution for this. If anyone knows how to deal with this or had some similar experience and found a solution I am looking forward to hearing from you!
As puce says, you have to use Task or Service for the things that you need to do in background. And Platform.runLater to do things in the JavaFX Application thread from the background thread.
You have to synchronize them, and one of the ways to do that is using the class CountDownLatch.
Here is an example:
Service<Void> service = new Service<Void>() {
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
//Background work
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
#Override
public void run() {
try{
//FX Stuff done here
}finally{
latch.countDown();
}
}
});
latch.await();
//Keep with the background work
return null;
}
};
}
};
service.start();
Use a Worker (Task, Service) from the JavaFX Application thread if you want to do something in the background.
http://docs.oracle.com/javafx/2/api/javafx/concurrent/package-summary.html
Use Platform.runLater from a background thread if you want to do something on the JavaFX Application thread.
http://docs.oracle.com/javafx/2/api/javafx/application/Platform.html#runLater%28java.lang.Runnable%29
It's too late to answer but for those who have the error, here is the solution XD
You can use one Thread.
Use the lambda expression for the runnable in the thread and the runlater.
Thread t = new Thread(() -> {
//Here write all actions that you want execute on background
Platform.runLater(() -> {
//Here the actions that use the gui where is finished the actions on background.
});
});
t.start();
You can user directly this code
Don't forget you can't send non-final variable in thread .
you can send final variable in thread
//final String me="ddddd";
new Thread(new Runnable() {
#Override
public void run() {
// me = me + "eee";
//...Your code....
}
}).start();
Use in
your code
try/catch
Could you let me know the reason for this error in SWT
"org.eclipse.swt.SWTException" Invalid Thread access ?
And How to fix such errors.
It happens when you try to act upon an interface item from a thread that's not the UI thread.
To run a code on the UI thread you have to use a Runnable and ask the display thread to run it. This way:
Display.getDefault().syncExec( new Runnable() {
#Override
public void run() {
// Do your job here
}
} );
As stated by the syncExec method javadoc,
the thread which calls this method is suspended until the runnable completes.
Also, you might check the asyncExec method.
In SWT you can access GUI resources only from the display thread. For example when setting the text in a org.eclipse.swt.widgets.Text control you must already be in the display thread or call
final Text text = ...;
Display.getCurrent().syncExec(new Runnable() {
#Override
public void run() {
text.setText("test");
}
});
I have a program which runs a thread. The thread performs processing all the time and it uses some synchronized queue.
The class snapshot is as follows:
public class MyClass:IDisposable
{
private Thread myThread = new Thread(threadFunc);
private volatile bool runThread = true;
public MyClass()
{
myThread.Start();
}
public Dispose()
{
runThread = false;
}
private void threadFunc()
{
try
{
while(runThread){
queue.Take(); //This method blocks the thread if queue is empty. It uses Monitor class
//do some processing
}
}
catch(Exception e){...}
}
private void otherFunc()
{
queue.enqueue(...);//this method is executed by main thread and uses lock while adding element to the queue.
}
}
When I call Dispose() method, the thread exists threadFunc() method, but after a sec I get an execption from this func "Unable to avaluate expression...", as if the tread was terminated while doing some work. Maybe it has just released from queue.Take() blocking and has no context to run. I know I'm missing something...
How can I solve such problem and terminate the thread from the Dispose method.
Many thanks!!!
Use the overload of Take that accepts a CancellationToken. You can get a reference to a token by using the CancellationTokenSource which also has the Cancel method that you can call from Dispose to unblock the Take method. You can read more cancellation here.
Use the poison pill approach: See this thread