How do I return a value from an anonymous class?
I have the following code.
As you can see, the method postTestResults
must return a boolean value.
Now the problem is that in postTestResults
I am creating an inner class AsyncHttpResponseHandler
and I am overriding onSuccess
and onFailure
to get the AsyncHttpResponseHandler result.
BUT if I put return true in onSuccess
and onFailure
obviously it doesn't work because onSuccess
u onFailure
should return void .
How can I handle 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;
}
thank
source to share
After calling MyRestClient.post
, there is still no information. At some point in the future, a call or onFailure is called. This asynchronous behavior is intended as you would otherwise have to wait for the trip message.
Do not return anything, or maybe the truth. And do the processing in a completely different way, handle the logic by calling something in onSuccess / onFailure.
You can make the result wait (absolutely horrible):
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 wiring, the semaphore stops execution of the current thread (due to 0 permissions in its constructor). When the callback (onSuccess / onFailure) is executed, the result is set (succeeds).
Local variables must be (effectively) final, so their object does not change. It's like callbacks on a different thread and the objects that the callbacks refer to are actual copies. Therefore, the understanding must be final. The result, however, must be recorded in, therefore, the bearer of value, the internal state of the final object, must be used. Hence, AtomicBoolean, like a final boolean
, cannot be written to.
By the way, Boolean
as a result, if the wrapper of the object (Boolean.TRUE, FALSE or null) Boolean
seems to be more appropriate.
source to share
In your example code, you are using an anonymous class, not an inner one.
Anonymous class is no different from regular classes. Its syntactic sugar that allows you to implement interfaces in place (without declaring a class name, javac will do it for you).
In your case, you should throw an exception into the method onFailure
, interrupting the execution of the code.
Since you are dealing with an asynchronous call, you do not know when the code will be executed. Therefore, before the call you want to succeed should be called from the method, onSuccess
or the application should wait at some place for the result of the callback.
source to share
You can add a system like this:
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);
}
}
MyAsyncState class:
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
}
}
source to share