Is there any way to get callback value out into main method.
public List<Passion> downloadpassion()
{
fsDB.getPassionvalue(new OnDownLoadPassionList() {
#Override
public List<Passion> OnResult(List<Passion> passionList) {
return passionList; //this is callback value
}
});
return passionList; //want passionList to pass here
}
you should make a interface like this
public interface EventListener{
void onListComplited(List<Passion> passionList)
}
and then add it as input for your function
public void downloadpassion(EventListener listener)
{
fsDB.getPassionvalue(new OnDownLoadPassionList() {
#Override
public List<Passion> OnResult(List<Passion> passionList) {
listener.onListComplited(passionList);
}
});
}
You can't return from a value within a callback.
Rewrite like this
public void downloadpassion(OnDownLoadPassionList onDownload) {
fsDB.getPassionvalue(onDownload);
}
In your other method
main() {
client.downloadpassion(new OnDownLoadPassionList() {
#Override
public List<Passion> OnResult(List<Passion> passionList) {
// TODO: use this callback value
}
});
}
Related
This is what I got to do
UploadCompleteListener is a custom interface that acts as a callback.
#Overrider
public Result doWork() {
mUpLoadDataService.uploadInspectionData(new UpLoadDataService.UploadCompleteListener() {
#Override
public void uploadComplete() {
return Result.success(); //this is what I want to do
}
#Override
public void uploadFailed(String reason) {
return Result.failure(); //this is what I want to do
}
});
return null;
}
Is it Possible?
If possible in any way please response soon. I can provide more details if you need it.
** This is what worked for me **
#NonNull
#Override
public Result doWork() {
final Result[] result = new Result[1];
mUpLoadDataService.uploadInspectionData(new UpLoadDataService.UploadCompleteListener() {
#Override
public void uploadComplete() {
result[0] = Result.success(); //this is what I want to do
}
#Override
public void uploadFailed(String reason) {
result[0] = Result.failure(); //this is what I want to do
}
});
return result[0];
}
public Result doWork(UpLoadDataService.UploadCompleteListener uploadListener) {
mUpLoadDataService.uploadInspectionData(uploadListener);
return null;
}
now pass the implementation from parent function. Lets say your parent function is named foobar
void foobar() {
someObject.doWork(new UpLoadDataService.UploadCompleteListener() {
#Override
public void uploadComplete() {
//write your logic here
return Result.success();
}
#Override
public void uploadFailed(String reason) {
//write your logic here
return Result.failure();
}
});
}
You have to realize that you are trying to get synchronously a result from an asynchronous call. This call is asynchronous for a reason, so the short answer is no, you can't.
Instead of returning a Result, you could return, for instance, a Future, which models the asynchronicity of the operation.
For android take a look at CallbackToFutureAdapter
https://developer.android.com/reference/kotlin/androidx/concurrent/futures/CallbackToFutureAdapter
https://developer.android.com/reference/java/util/concurrent/Future
You could use EventBus to notify Subscribed methods in every place you want like so:
public class MessageEvent {
public final String message;
public MessageEvent(String message) {
this.message = message;
}
}
public void doWork() {
mUpLoadDataService.uploadInspectionData(new UpLoadDataService.UploadCompleteListener() {
#Override
public void uploadComplete() {
EventBus.getDefault().post(new MessageEvent("success"));
}
#Override
public void uploadFailed(String reason) {
EventBus.getDefault().post(new MessageEvent("failed"));
}
});
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}
See this implementation guide.
You can get the callback of your task using the following way
doWork(paremter, new ServiceListener<String>() { //paremter if any
#Override
public void success(String obj) {
//get the response if success
}
#Override
public void fail(ServiceError error) {
//get the error response
}
});
do the work and send the call response from where it called
private void doWork(String param , ServiceListener<String> serviceListener) {
mUpLoadDataService.uploadInspectionData(new UpLoadDataService.UploadCompleteListener() {
#Override
public void uploadComplete() {
serviceListener.success("success");
}
#Override
public void uploadFailed(String reason) {
serviceListener.fail(new ServiceError("Can not Upload"));
}
});
}
ServiceListener interface will be defined as follow
public interface ServiceListener<T> {
void success(T obj);
void fail(ServiceError error);
}
public class ServiceError {
public Throwable errorObject;
public String message;
public ServiceError(){
message = "";
}
public ServiceError(String message){
this.message = message;
}
public ServiceError(String message, Throwable errorObject){
this.message = message;
this.errorObject = errorObject;
}
public Object getErrorObject() {
return errorObject;
}
public void setErrorObject(Throwable errorObject) {
this.errorObject = errorObject;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
For example, if I wanted to do something like this to call a method:
myLights.addLight(new Fluorescent(lumens));
in order to create a new object in the Fluorescent class and pass down the lumens data. How would I then set up the method to receive this?
Assuming method is not returning anything.
void addlight(Fluorescent a){
// your logic
}
In your Lights class create a method that accepts a Fluorescent object as an argument.
public void addLight(Fluorescent fluorescent){
// do something
}
Here is a basic example:
public class HelloWorld
{
public static void main(String[] args)
{
Light light = new Light();
light.addLight(new Fluorescent("300 lm"));
System.out.print(light.getLumen());
}
}
public class Light {
private String lumen;
public Light() {
}
public void setLumens(String lumen){
this.lumen = lumen;
}
public String getLumen(){
return this.lumen;
}
public void addLight(Fluorescent fluorescent) {
if(fluorescent.getLumen() != null) {
this.lumen = fluorescent.getLumen();
}
}
}
public class Fluorescent {
private String lumen;
public Fluorescent(String lumen){
this.lumen = lumen;
}
public void setLumen(String lumen){
this.lumen = lumen;
}
public String getLumen(){
return this.lumen;
}
}
Seeing that a Fluorescent is a Light, you might want to look in to inheritance.
Look here for some explanation
Java 101: Inheritance in Java, Part 1
public class Fluorescent() {
public Fluorescent(String lumens) {
// do something
}
}
public class Lights() {
public void addLight(Fluorescent fluorescent) {
// do something
}
}
I'm using a multiplayer Game Client that's called AppWarp (http://appwarp.shephertz.com), where you can add event listeners to be called back when event's happen, let's assume we'll be talking about the Connection Listener, where you need to implement this interface:
public interface ConnectionRequestListener {
void onConnectDone(ConnectEvent var1);
void onDisconnectDone(ConnectEvent var1);
void onInitUDPDone(byte var1);
}
My goal here is to mainly create a Reactive version of this client to be used in my Apps Internally instead of using the Client itself directly (I'll also rely on interfaces later instead of just depending on the WarpClient itself as in the example, but that's not the important point, please read my question at the very end).
So what I did is as follows:
1) I introduced a new event, named it RxConnectionEvent (Which mainly groups Connection-Related events) as follows:
public class RxConnectionEvent {
// This is the original connection event from the source client
private final ConnectEvent connectEvent;
// this is to identify if it was Connection / Disconnection
private final int eventType;
public RxConnectionEvent(ConnectEvent connectEvent, int eventType) {
this.connectEvent = connectEvent;
this.eventType = eventType;
}
public ConnectEvent getConnectEvent() {
return connectEvent;
}
public int getEventType() {
return eventType;
}
}
2) Created some event types as follows:
public class RxEventType {
// Connection Events
public final static int CONNECTION_CONNECTED = 20;
public final static int CONNECTION_DISCONNECTED = 30;
}
3) Created the following observable which emits my new RxConnectionEvent
import com.shephertz.app42.gaming.multiplayer.client.WarpClient;
import com.shephertz.app42.gaming.multiplayer.client.events.ConnectEvent;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Action0;
import rx.subscriptions.Subscriptions;
public class ConnectionObservable extends BaseObservable<RxConnectionEvent> {
private ConnectionRequestListener connectionListener;
// This is going to be called from my ReactiveWarpClient (Factory) Later.
public static Observable<RxConnectionEvent> createConnectionListener(WarpClient warpClient) {
return Observable.create(new ConnectionObservable(warpClient));
}
private ConnectionObservable(WarpClient warpClient) {
super(warpClient);
}
#Override
public void call(final Subscriber<? super RxConnectionEvent> subscriber) {
subscriber.onStart();
connectionListener = new ConnectionRequestListener() {
#Override
public void onConnectDone(ConnectEvent connectEvent) {
super.onConnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_CONNECTED));
}
#Override
public void onDisconnectDone(ConnectEvent connectEvent) {
super.onDisconnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_DISCONNECTED));
}
// not interested in this method (for now)
#Override
public void onInitUDPDone(byte var1) { }
private void callback(RxConnectionEvent rxConnectionEvent)
{
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(rxConnectionEvent);
} else {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
};
warpClient.addConnectionRequestListener(connectionListener);
subscriber.add(Subscriptions.create(new Action0() {
#Override
public void call() {
onUnsubscribed(warpClient);
}
}));
}
#Override
protected void onUnsubscribed(WarpClient warpClient) {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
4) and finally my BaseObservable looks like the following:
public abstract class BaseObservable<T> implements Observable.OnSubscribe<T> {
protected WarpClient warpClient;
protected BaseObservable (WarpClient warpClient)
{
this.warpClient = warpClient;
}
#Override
public abstract void call(Subscriber<? super T> subscriber);
protected abstract void onUnsubscribed(WarpClient warpClient);
}
My question is mainly: is my implementation above correct or should I instead create separate observable for each event, but if so, this client has more than 40-50 events do I have to create separate observable for each event?
I also use the code above as follows (used it in a simple "non-final" integration test):
public void testConnectDisconnect() {
connectionSubscription = reactiveWarpClient.createOnConnectObservable(client)
.subscribe(new Action1<RxConnectionEvent>() {
#Override
public void call(RxConnectionEvent rxEvent) {
assertEquals(WarpResponseResultCode.SUCCESS, rxEvent.getConnectEvent().getResult());
if (rxEvent.getEventType() == RxEventType.CONNECTION_CONNECTED) {
connectionStatus = connectionStatus | 0b0001;
client.disconnect();
} else {
connectionStatus = connectionStatus | 0b0010;
connectionSubscription.unsubscribe();
haltExecution = true;
}
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
fail("Unexpected error: " + throwable.getMessage());
haltExecution = true;
}
});
client.connectWithUserName("test user");
waitForSomeTime();
assertEquals(0b0011, connectionStatus);
assertEquals(true, connectionSubscription.isUnsubscribed());
}
I suggest you avoid extending the BaseObservable directly since it's very error prone. Instead, try using the tools Rx itself gives you to create your observable.
The easiest solution is using a PublishSubject, which is both an Observable and a Subscriber. The listener simply needs to invoke the subject's onNext, and the subject will emit the event. Here's a simplified working example:
public class PublishSubjectWarpperDemo {
public interface ConnectionRequestListener {
void onConnectDone();
void onDisconnectDone();
void onInitUDPDone();
}
public static class RxConnectionEvent {
private int type;
public RxConnectionEvent(int type) {
this.type = type;
}
public int getType() {
return type;
}
public String toString() {
return "Event of Type " + type;
}
}
public static class SimpleCallbackWrapper {
private final PublishSubject<RxConnectionEvent> subject = PublishSubject.create();
public ConnectionRequestListener getListener() {
return new ConnectionRequestListener() {
#Override
public void onConnectDone() {
subject.onNext(new RxConnectionEvent(1));
}
#Override
public void onDisconnectDone() {
subject.onNext(new RxConnectionEvent(2));
}
#Override
public void onInitUDPDone() {
subject.onNext(new RxConnectionEvent(3));
}
};
}
public Observable<RxConnectionEvent> getObservable() {
return subject;
}
}
public static void main(String[] args) throws IOException {
SimpleCallbackWrapper myWrapper = new SimpleCallbackWrapper();
ConnectionRequestListener listner = myWrapper.getListener();// Get the listener and attach it to the game here.
myWrapper.getObservable().observeOn(Schedulers.newThread()).subscribe(event -> System.out.println(event));
listner.onConnectDone(); // Call the listener a few times, the observable should print the event
listner.onDisconnectDone();
listner.onInitUDPDone();
System.in.read(); // Wait for enter
}
}
A more complex solution would be to use one of the onSubscribe implementations to create an observable using Observable.create(). For example AsyncOnSubscibe. This solution has the benefit of handling backperssure properly, so your event subscriber doesn't become overwhelmed with events. But in your case, that sounds like an unlikely scenario, so the added complexity is probably not worth it.
I have a problem with this async call:
public class myClass {
protected final int idObj;
public void myMethod() {
myService.getObj( new AsyncCallback<List<Object>>() {
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(List<Object> listObject) {
idObj = listObject.get(0).getIdObj();
}
});
if(idObj == 1) {
//do something
}
}
}
The value idObj is equal zero at the first time and this if block isn't execute.
How to avoid this?
It's an asynchronous call, that means that the code executed in your onSuccess method will be executed later.
So the if statement is executed but at this time your value still 0.
You should put your if statement in the onSuccess method.
I'm implementing a class that is responsible for all my HTTP requests from the Blackberry. I have around 10 or so screens that use this class to query a web service and get data from it. What would be the standard pattern to use in this case?
Currently I have it setup as follows -
public class NetworkAccessClass
{
public NetworkAccessClass(String url, String methodName, Vector paramNames, Vector paramValues, MainScreen screen) {
// perform inits
}
public void run() {
// Get Data
if(screen.instanceOf(LoginScreen)) {
((LoginScreen) screen).requestSucceded(responseData);
}
// So on for all 10 screens.
catch() {
((LoginScreen) screen).requestFailed(errorCode);
// So on for all 10 screens.
}
}
}
It works, but doesn't look right, and if a single screen has multiple types network requests, I'm being forced to add a flag to keep track of which function it's supposed to call back.
Is there a better way to do this?
Thanks,
Teja.
Use a callback interface, e.g. ResponseHandler:
public class NetworkAccessClass
{
public interface ResponseHandler {
void requestSucceeded(ResponseData responseData);
void requestFailed(ErrorCode errorCode);
}
public NetworkAccessClass(
String url,
String methodName,
Vector paramNames,
Vector paramValues,
ResponseHandler responseHandler) {
// perform inits
}
public void run() {
// Get Data
try {
...
responseHandler.requestSuceeded(responseData);
catch() {
responseHandler.requestFailed(errorCode);
}
}
}
This hopefully decouples your NetworkAccessClass from knowing about all the screens. Then either your screens implement NetworkAccessClass.ResponseHandler or they pass an adapter handler (anonymous inner class) to call the proper methods on the screen, e.g.
class LoginScreen {
...
new NetworkAccessClass(url, methodName, paramNames, paramValues,
new ResponseHandler() {
#Override
void requestSucceeded(ResponseData responseData) {
LoginScreen.this.handleLoginSuccess(responseData);
}
#Override
void requestFailed(ErrorCode errorCode) {
LoginScreen.this.handleLoginFailure(errorCode);
}
}
...
}
You could use a listener, which is a simple interface the network class would call back whenever something interesting happens :
public interface NetworkListener {
void requestSucceeded(byte[] responseData);
void requestFailed(int errorCode);
}
public class NetworkAccess {
// ...
public void run() {
// Get Data
if (successful) {
fireSucess(responseData);
}
catch(SomeException e) {
fireFailure(errorCode);
}
}
public void addNetworkListener(NetworkListener listener) {
// add listener to list of listeners
}
private void fireSuccess(byte[] responseData) {
for (NetworkListener l : listeners) {
l.requestSucceeded(responseData);
}
}
// ...
}
public class LoginScreen {
private void foo() {
NetworkAccess access = new NetworkAccess(...);
access.addNetworkListener(new NetworkListener() {
public void requestSucceeded(byte[] responseData) {
// do what you want
}
public void requestFailed(int errorCode) {
// do what you want
}
});
}
}
This is known as the Observable/observer pattern. The observable notifies its observers when something happens, but without having to know their exact type. The listsner class decouples the two parties.