I have the following code.
As you can see the method postTestResults
should return a Boolean.
Now the problem is that in postTestResults
I create a inner class AsyncHttpResponseHandler
and I override onSuccess
and onFailure
to get the result of the AsyncHttpResponseHandler.
BUT if I put return true in onSuccess
and onFailure
obviously it does not work, because onSuccess
and onFailure
must return void.
Please how do I cope with such a scenario?
public static Boolean postTestResults(DBManager db, String mDeviceId,
String mFirmwareVer, String mJobNo, int mTestType, Activity activity) {
MyRestClient.post(possibleEmail, device, results, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
return true; // does not work!
}
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2, Throwable arg3) {
// TODO Auto-generated method stub
}
});
return null;
}
Thanks
After calling MyRestClient.post
there still is no information available. At some time in the future onSuccess or onFailure is called. This asynchrone behaviour is intended, as you otherwise would have to wait for the a communication trip.
Do not return anything, or maybe true. And do the processing entirely differently, handle the logic by calling something in onSuccess/onFailure.
You could force a wait on the result (absolutely horrible) by:
final Semaphore semaphore = new Semaphore(0);
final AtomicBoolean succeeded = new AtomicBoolean();
MyRestClient.post(possibleEmail, device, results, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
succeeded.set(true);
semaphore.release();
}
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2, Throwable arg3) {
succeeded.set(false);
semaphore.release();
}
});
semaphore.aquire();
return succeeded.get();
After calling the posting, the semaphore halts the current thread's execution (because of 0 permits in its constructor). When a callback is done (onSuccess/onFailure) a result is set (succeeded).
The local variables must be (effectively) final, so their object does not change. This is as the callbacks are in another thread, and the objects referenced in the callbacks are actual copies. So for understanding the must be final. The result however must be written to, hence a value holder, internal state of a final object must be used. Hence the AtomicBoolean, as a final boolean
cannot be written to.
By the way, Boolean
as result if an object wrapper (Boolean.TRUE, FALSE or null), boolean
seems more appropriate.
In your code example you use annonymous class not inner.
Annonymous class does not differ from regular classes. Its a syntax sugar that allow you to implement interfaces in place (without declaring class name, javac will do this for you).
In your case you should throw an exception in method onFailure
order by interrupt the execution of code.
Because you deal with asynchronic call, you do not know when the code will be executed. There fore the task you wan to perform on success should be invoked from method onSuccess
or the application should wait in some place for the result of the call back.
You can add a system like that :
public class MyAsync extends AsyncHttpResponseHandler{
private final MyAsyncState state;
public MyAsync(MyAsyncState state){
this.state = state;
}
public void onSuccess(......){
this.state.setResult(true);
}
public void onFailure(.....){
this.state.setResult(false);
}
}
An the class MyAsyncState :
public class MyAsyncState{
private Boolean state;
public void setResult(boolean b){
this.state = b;
doIt();
}
private void doIt(){
// do what you want
// show popup for example
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With